From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- obsolete/dviware/dvi2xx/dvi2xx.c | 4634 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 4634 insertions(+) create mode 100644 obsolete/dviware/dvi2xx/dvi2xx.c (limited to 'obsolete/dviware/dvi2xx/dvi2xx.c') diff --git a/obsolete/dviware/dvi2xx/dvi2xx.c b/obsolete/dviware/dvi2xx/dvi2xx.c new file mode 100644 index 0000000000..8c0959bce9 --- /dev/null +++ b/obsolete/dviware/dvi2xx/dvi2xx.c @@ -0,0 +1,4634 @@ +#define VERSION "0.51alpha9" +/********************************************************************** + **************************** Intro ********************************* + ********************************************************************** + * This program translates TeX's DVI-Code into device dependent + * code of either the + * + * - HP-LASERJET+ and compatibles (PCL), or the + * - IBM 3812 pageprinter + * + * depending on the preprocessor switches specified before compilation. + * The program is written to run on a PC XT/AT/PS2 under MS-DOS. It can + * be compiled nicely with MSC Rel. 3.0-5.1 with option -AL (large memory + * model). Take care that in the CONFIG.SYS file the FILES parameter + * is set to 20; otherwise reduce MAXOPEN. 640K are recommended. + * I use link option /stack:9000 to increase runtime stack. + * It also works without modifications under Unix System V. + ********************************************************************** + * Adapted for the PC: Gustaf Neumann + * +1002 stuff University of Economics + * +3812 support Augasse 2-6 + * +Output buffering A-1090 Vienna, AUSTRIA + * +lpt binary support Tel. *43-222-340525/533 + * +pk-89 stuff 773 + * +pixelpaths + * +alternative directory structure + * +code compiles also under Unix V (HP/UX) + * (thx Michael Haberler) + * +huge characters (a character bigger than 32K) + * formats PXL1001 and PXL 1002 + * (use: raster graphics) + * +reduction of the produced code + * +new options -X -Y -c -g + * +changed options -r (LJ now default from first to last) + * -x,-y (accept floats) + * +new option -z for LJ: print testpage containing + * pagecounter after printjob + * +try to overcome font limit on LJ (max 16 fonts/page) and + * (max 32 fonts/document): + * additional fonts are drawn as bitmap- + * graphics. + * +allows to set character close to the paperedge on LJ + * +gf-supprt (by Joe Kelsey joe@Pacer.com) + * gf.c and gf.h from mitdevices/dvi2ps + * +clipping of rules + * +OS/2 defines from Rutger Berns, apprmb@hheouh50.bitnet + * + * BITNET/EARN: NEUMANN at AWIWUW11 + ********************************************************************** + * fixes in LJ-mode: rule-drawing, + * characters with 127<=height<=200 + * reset printer at beginning and end of each job + * better positioning of rules + * 30.1.89 (0.48) bug fixed for files containing >32 fonts (thanks A. Brosig), + * different font assignment heuristic + * fixes in 3812-mode: 14.juli 87 positioning of rastered characters + * better positioning of rules + * general fixes + * 1.1.88 page origin set to 1in/1in (hopefully everywhere) + * 22.7.88 reset y-position for each page-eject + * 15.1.89 fixing bug is space allocation for EmitFileName + * (thanks to Bernhard Simon) + * 15.3.91 (0.49) landscape support for lj ii p, lj iii and lj 2000 + * fixing rule drawing problems for IBM3812 in landcape mode, + * 256 character clean (lj family and IBM3812) + * 5.5.91 (0.50) -DSEVENBIT added for older LJ-emulations + * -D1, -D2, -D-, -D1-, -D2- options added due to suggestions + * from Tomasz Wolniewicz + ********************************************************************** + * Preprocessor switches: + * #define DEBUG for massive printing of trace information + * when -d cmdline option specified + * #define IBM3812 produce output for the IBM3812 pageprinter + * #define LJ produce output for the HP Laserjet+ or LJ II + * #define LJ2P produce output for the HP Laserjet LJ IIP, LJ III + * or LaserJet 2000 + * #define LJ_LARGE_FONT_MEMORY large FONT Memory for LJ printer family + * #define DRAWGLYPH draws PK-Glyphs on stderr + * #define USEPXL use PXL and PK fonts rather than gf fonts + */ +/********************************************************************** + ************************ Global Definitions ************************ + **********************************************************************/ +/* #define IBM3812 */ +/* #define LJ */ +/* #define DRAWGLYPH */ + +#include "config.h" + + +#include "commands.h" +#include +#include +#include +#include +#ifdef vms +#include +#else +#include +#endif +#ifdef MSDOS +#include /* only for binaryopen on device */ +#endif +#ifdef unix +#include +#endif + +#define DVIFORMAT 2 +#define UNKNOWN -1 +#define FIRSTFNTCHAR 0 + +#ifdef OPEN_MAX /* ... in a friendly unix system */ +#ifndef vms +#define MAXOPEN_OS (OPEN_MAX - 8) +#else +#define MAXOPEN_OS 12 /* OPEN_MAX seems to be 8 on VMS systems */ +#endif +#else +#define MAXOPEN_OS 12 /* limit on number of open font files */ +#endif + +#ifdef LJ_RESIDENT_FONTS +/* we have to read tfm files as well */ +#define MAXOPEN (MAXOPEN_OS - 1) +#else +#define MAXOPEN MAXOPEN_OS +#endif + +#define NFNTCHARS LASTFNTCHAR+1 +#define STACK_SIZE 100 /* DVI-stack size */ +#define NONEXISTANT -1 /* offset for PXL files not found */ +#define NO_FILE ((FILE *)-1) +#define NEW(A) ((A *) malloc(sizeof(A))) +#define EQ(a,b) (strcmp(a,b)==0) +#define MM_TO_PXL(x) (int)(((x)*RESOLUTION*10)/254) +#define PT_TO_PXL(x) (int)((long)((x)*RESOLUTION*100l)/7224) +#define PT_TO_DVI(x) (long)((x)*65536l) +#define BOPENCMD fopen +#define BINOPEN(f) BOPENCMD(f,READ_BINARY) +/* SMALL_SIZE characters are loaded into font storage of the printer */ +/* LARGE_SIZE characters are rastered */ +/* HUGE_SIZE characters are not loaded into the memory of the host */ +#define SMALL_SIZE (unsigned char) 0 +#define LARGE_SIZE (unsigned char) 1 +#define HUGE_SIZE (unsigned char) 2 +#define HUGE_CHAR_PATTERN 32767l +#define BYTES_PER_PIXEL_LINE 500 /* max number of bytes per pixel line */ + + +#define PK_POST 245 +#define PK_PRE 247 +#define PK_ID 89 + +/* to speedup the program a little: redefinition of PixRound and PutWord */ +/*#define PIXROUND(x,c) ((((double)x+(double)(c>>1))/(double)c)+0.5)*/ +#define PIXROUND(x,c) (((x)+c)/c) +#define PUTWORD(w) EMITC((char)(w>>8)&0xff); EMITC((char)w&0xff) +/*************************************************************************/ +#define EMIT fprintf /* output a formatted string */ +#ifndef vms +#define EMITB(len,b) fwrite(b,1,len,outfp) /* output binary data of len */ +#else + /* VMS doesn't like to use fwrite on a file with fixed record sizes, + so use number of putc calls */ +#define EMITB(len,b) for (kk = 0;kk < len; kk++) putc(*(b+kk),outfp); +#endif +#define EMITWORD(w) PUTWORD((w)) /* output a 2 byte word of data */ + +#define MoveOver(b) h += (long) b +#define MoveDown(a) v += (long) a +#define qfprintf if (!G_quiet) fprintf +#define qprintf if (!G_quiet) printf +#define LARGER(a,b) (((a)>(b)) ? (a) : (b)) + +#ifdef IBM3812 +#define PRINTER "IBM 3812 pageprinter" +#define EMITC(c) PMPoutC(c) /* output a single character */ +#define PMPcont(l) PMPout(-1,(long)l) /* next l bytes continuous */ +#define PMPflush PMPout(0l,"") /* flush PMP-buffer */ +#define EMITL(l,d) PMPout((int)l,d) /* EMIT-logical: via PMP-buffer */ +#define hconvRESOLUTION 240 +#define vconvRESOLUTION 240 +#define CHAR_WIDTH_LARGE 100 /* limit for loading into printer font */ +#define CHAR_HEIGTH_LARGE 127 /* limit for loading into printer font */ +#define OUTBUFSIZE 20000 /* size of output buffer for PMP cmds */ + /* has to be less max(signed int) */ +#define MAXFONTSTORAGE 130000l /* font storage in the 3812 pageprinter */ +#define EMITFILE_EXTENSION ".pmp" /* default extension of emit file */ +#define XDEFAULTOFF RESOLUTION /* y default offset on page 1 inch */ +#define YDEFAULTOFF RESOLUTION /* y default offset on page 1 inch */ +#define CHARSTRINGMAX 80 /* bufferlength for SetString */ +#define MAX_PAGE_WIDTH 2040 +#define MAX_PAGE_HEIGHT 3360 +/**********************************************************************/ +/************** Positioning for the 3812 ****************************/ +/**********************************************************************/ +#define VERT_HALF(n) ((short)((n+1)>>1)-1) +#define HOR_HALF(n) ((short)(n>>1)) +#define MoveHor(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\342"); EMITWORD((n)); } +#define MoveVert(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\343"); EMITWORD((n)); } +#endif + +#ifdef LJ +#ifdef LJ4 +#define PRINTER "HP Laserjet IV" +#else +#ifdef LJ2P +#define PRINTER "HP LaserJet IIP" +#else +#ifdef LJ2 +#define PRINTER "HP LaserJet II" +#else +#define PRINTER "HP LaserJet" +#endif +#endif +#endif +#define hconvRESOLUTION RESOLUTION +#define vconvRESOLUTION RESOLUTION +#ifdef LJ2 +/* the printer limit of the LJ2P is actually 16384x16384, + * but to exploit it, one would need lots of memory in the printer + */ +#define CHAR_WIDTH_LARGE 200 /* limit for loading into printer font */ +#define CHAR_HEIGTH_LARGE 255 /* y_offset reaches the same size! */ +#else /* such as LaserJet+, Laserjet II */ +#define CHAR_WIDTH_LARGE 100 /* limit for loading into printer font */ +#define CHAR_HEIGTH_LARGE 127 /* y_offset reaches the same size! */ +#endif +#define EMITFILE_EXTENSION ".lj" /* default extension of emit file */ +#ifndef MAX_FONTS_PER_PAGE +#define MAX_FONTS_PER_PAGE 16 /* maximum number of fonts per page */ +#endif +#define HANDLE_MAX_FONTS 255 /* max nr of fonts handled (rasterfont) */ +#define FONTS_DOWNLOADABLE 32 /* max nr of fonts that can be downloaded */ +#define MAXFONTSTORAGE (395l*1024l) /* standard user memory */ +#define EMITC(c) putc(c,outfp) /* output a single character */ +#define EMITL(l,d) EMITB(l,d) /* EMIT-logical = EMITB */ +#define XDEFAULTOFF RESOLUTION-54 /*x default offset on page 1 inch (LJ2)*/ +#define YDEFAULTOFF RESOLUTION+9 /* y default offset on page 1 inch */ +#define max(x,y) if ((y)>(x)) x = y +#ifndef vms +#define INT_ASCII(b,i) if (i == 0) b[0] = '\0'; else sprintf((char *)b,"%hd",i) +#else +#define INT_ASCII(b,i) if (i == 0) b[0] = '\0'; else sprintf((char *)b,"%d",i) +#endif +#endif + +#ifdef SEVENBIT +#define VIS 33 +#define VIS2 (VIS+32) +unsigned char +VisChar(c) +unsigned char c; +{ + c &= 0xff; + if (c < VIS) + return ((unsigned char)(160 + c)); + if (c < 128) + return (c); + if (c < (255 - VIS2)) + return ((unsigned char)(VIS2 + c)); + return (255); +} +#else +#define VisChar(c) (unsigned char)(c) +#endif + + +/**********************************************************************/ +/*********************** external definitions ***********************/ +/**********************************************************************/ + +#ifndef _AMIGA +#ifndef unix +long access(); +FILE *BOPENCMD(); +void exit(); +int fclose(); +int fprintf(); +int fseek(); +char *index(); +int printf(); +int sscanf(); +int strcmp(); +char *strcpy(); +#ifdef MSC5 +unsigned int strlen(); +#endif +void free(); +void setbuf(); +#endif + +#ifdef MSDOS +int intdos(); +#else +char *malloc(); +char *getenv(); +int atoi(); +#endif +#endif + + +#ifndef USEPXL +/* interface to gf.c */ +extern FILE *gfin; +extern int checksum; +extern long tfm_wd[], char_pointer[]; +extern char char_exists[]; +extern int num_cols, num_rows, num_bytes, x_offset, y_offset; +extern unsigned char bits[]; +extern int gf_font_max_m, gf_font_max_n, gf_font_min_n; +extern int gettochar(); +extern void readbits(); +extern void readpost(); +extern void seekpost(); +extern int seekchar(); +#endif + + +/**********************************************************************/ +/************************* Global Procedures ************************/ +/**********************************************************************/ +/* Note: Global procedures are declared here in alphabetical order, with + those which do not return values typed "void". Their bodies occur in + alphabetical order following the main() procedure. The names are + kept unique in the first 6 characters for portability. */ +double ActualFactor(); +void AllDone(); +#ifdef MSDOS +void AssureBinary(); /* DOS and Microsoft C dependent !!! */ +#endif +void CopyFile(); +void CopyHPFile(); +void DecodeArgs(); +void DoBop(); +long DoConv(); +void DoSpecial(); +void EmitChar(); +void Fatal(); +void FindPostAmblePtr(); +void FormFeed(); +void GetBytes(); +void GetFontDef(); +char *GetKeyStr(); +bool GetKeyVal(); +bool IsSame(); +void lcase(); +void LoadAChar(); +long NoSignExtend(); +/* see cautionary note in code, re arithmetic vs logical shifts */ +void OpenFontFile(); +long PixRound(); +void PkRaster(); +void PutWord(); +void RasterLine(); +void RasterChar(); +void ReadFontDef(); +void ReadPostAmble(); +void SetChar(); +void SetFntNum(); +void SetPosn(); +void SetRule(); +void SetString(); +long SignExtend(); +/* see cautionary note in code, re arithmetic vs logical shifts */ +void SkipFontDef(); +void Warning(); +unsigned char skip_specials() ; + +#ifdef IBM3812 +void PMPout(); +void PMPoutC(); +#endif + +/**********************************************************************/ +/*********************** Font Data Structures ***********************/ +/**********************************************************************/ + +struct char_entry { /* character entry */ +#ifdef USEPXL + unsigned short width, height; /* width and height in pixels */ + short xOffset, yOffset, yyOffset; /* x offset and y offset in pixels*/ +#endif + struct { + bool isloaded; + union { + long fileOffset; + long *pixptr; + } address; + } where; + long tfmw; /* TFM width */ + long cw; /* character width in pixels */ + unsigned char flag_byte; /* for PK-files */ + unsigned char charsize; +}; +struct font_entry { /* font entry */ + long k, c, s, d; + int a, l; + char n[STRSIZE]; /* FNT_DEF command parameters */ + long font_mag; /* computed from FNT_DEF s and d parameters */ + /*char psname[STRSIZE];*/ /* PostScript name of the font */ + char name[STRSIZE]; /* full name of PXL file */ + FILE * font_file_id; /* file identifier (NO_FILE if none) */ +#ifdef USEPXL + long magnification; /* magnification read from PXL file */ + long designsize; /* design size read from PXL file */ +#endif + struct char_entry ch[NFNTCHARS]; /* character information */ + struct font_entry *next; + unsigned short ncdl; /* #of different chars actually downloaded */ + unsigned short plusid; /* Font id in Printer */ + bool used_on_this_page; +#ifdef LJ_RESIDENT_FONTS + bool resident_p; /* is font resident in printer? */ + char symbol_set[40]; /* symbol set value (resident fonts) */ + unsigned short resid; /* typeface id (resident fonts) */ + unsigned spacing; /* 0=monospace, 1=variable (resident fonts) */ + unsigned style; /* upright/italic/... (resident fonts) */ + int weight; /* regular/bold/... (resident fonts) */ + double pitch; /* chars per inch (monospaced resident fonts)*/ +#endif + enum PxlId { + id1001, id1002, pk89 } id; +#ifdef LJ + unsigned short max_width, max_height, max_yoff; +#endif +}; + + +struct pixel_list { + FILE *pixel_file_id; /* file identifier */ + int use_count; /* count of "opens" */ +}; +/**********************************************************************/ +/************************* Global Variables *************************/ +/**********************************************************************/ +long FirstPage = -1000000; /* first page to print (uses count0) */ +long LastPage = 1000000; /* last page to print */ +long PrintPages = 1000000; /* nr of pages to print */ +bool FirstPageSpecified = FALSE; +bool LastPageSpecified = FALSE; +char G_progname[STRSIZE]; /* program name */ +char filename[STRSIZE]; /* DVI file name */ +char rootname[STRSIZE]; /* DVI filename without extension */ +char *PXLpath = FONTAREA; /* PXL path name for search */ +char *HeaderFileName = ""; /* file name & path of Headerfile */ +char *EmitFileName = ""; /* file name & path for output */ +#ifdef IBM3812 +bool FirstAlternate = FALSE; /* first page from alternate casette ? */ +#endif +bool Reverse = FALSE; /* process DVI pages in reverse order? */ +bool Landscape = FALSE; /* print document in ladscape mode */ +bool ResetPrinter = TRUE; /* reset printer at the begin of the job*/ +bool DoublePage = FALSE; /* print on both sides of a paper */ +bool PrintSecondPart = TRUE; /* print First Part when DoublePage */ +bool PrintFirstPart = TRUE; /* print Second Part when DoublePage */ +bool PrintEmptyPages = TRUE; /* print Empty pages in DoublePage mode*/ +short PageParity = 1; +#ifdef MAKETEXPK +bool makeTexPK = TRUE; +#endif + +#ifdef LJ +#ifdef LJ2P +int DuplexMode = 0; +#endif +#ifdef LJ4 +bool econoMode = FALSE; +#endif +bool PrintTestPage = FALSE; /* print testpage with pagecounter after job */ +unsigned short pagesize = 0; /* page size value */ +unsigned short pgsiz_dots = 0; /* page size in dots (for rule-clipping)*/ +#endif + + +#ifndef vms +short G_errenc = 0; /* has an error been encountered? */ +#else +long G_errenc = SS$_NORMAL; /* has an error been encountered? */ +#endif +bool G_header = FALSE; /* copy header file to output? */ +bool G_quiet = FALSE; /* for quiet operation */ +bool G_noverbatim = TRUE; /* inform user about pxl-files used */ +bool G_nowarn = FALSE; /* don't print out warnings */ +short x_origin = XDEFAULTOFF; /* x-origin in dots */ +short y_origin = YDEFAULTOFF; /* y-origin in dots */ +short x_goffset; /* global x-offset in dots */ +short y_goffset; /* global y-offset in dots */ +unsigned short ncopies = 1; /* number of copies to print */ +long hconv, vconv; /* converts DVI units to pixels */ +long den; /* denominator specified in preamble */ +long num; /* numerator specified in preamble */ +long h; /* current horizontal position */ +long hh = 0; /* current h on device */ +long v; /* current vertical position */ +long vv = 0; /* current v on device */ +long mag; /* magnification specified in preamble */ +long usermag = 0; /* user specified magnification */ +int ndone = 0; /* number of pages converted */ +int nopen = 0; /* number of open PXL files */ +#ifdef vms +int kk; /* loop variable for EMITB */ +#endif +FILE *outfp = NULL; /* output file */ +FILE *pxlfp; /* PXL file pointer */ +FILE *dvifp = NULL; /* DVI file pointer */ +struct font_entry *prevfont = NULL; /* font_entry pointer previous font*/ +struct font_entry *fontptr; /* font_entry pointer */ +struct font_entry *hfontptr = NULL; /* font_entry pointer */ +struct font_entry *pfontptr = NULL; /* previous font_entry pointer */ +struct pixel_list pixel_files[MAXOPEN+1]; /* list of open PXL files */ +long postambleptr; /* Pointer to the postamble */ +long ppagep; /* previous page pointer */ +static int last_ry = UNKNOWN; /* last y-position on page */ +static int last_rx = UNKNOWN; /* last x-position on page */ +long StartPrintPages; /* notpad for double paged output */ +int WouldPrint = 0; +bool ZeroPage = FALSE; /* Document starts with a Zero Page */ +bool EvenPage = FALSE; /* Document starts with an even Page */ +long LastPtobePrinted = 0; +int G_ncdl = 0; + +long allocated_storage = 0; /* size of mallocated storage (statistics) */ +long power[32] ; +long gpower[33] ; + + +#ifdef DEBUG +int Debug = 0; +#endif + +#ifdef LJ +int fonts_used_on_this_page = MAX_FONTS_PER_PAGE+1; +char rasterfont[HANDLE_MAX_FONTS]; + /* raster if fonts/page>MAX_FONTS_PER_PAGE*/ +#ifdef LJ_RESIDENT_FONTS +unsigned resident_count = 0; +char *TFMpath = DEFAULT_TFM_PATH; +#endif +#endif + +long used_fontstorage = 0; + +#ifdef IBM3812 +char PMPformat[20]; +char CharString[CHARSTRINGMAX]; +unsigned int CharStringPos = 0; +#define CharStringOut \ + if (CharStringPos>0) { \ + PMPcont(CharStringPos+1);\ + PMPoutC((unsigned char)CharStringPos);\ + PMPout(CharStringPos, CharString); \ + CharStringPos=0; } +#endif + +#ifdef TIMING +/************************timing stuff*********************/ +#ifdef BSD_TIME_CALLS +#ifndef vms +#include +#else +#include +#endif +struct timeb timebuffer; +double start_time; +#else +#include +struct timeval Tp; +double start_time; +#endif +#endif + + + +/**********************************************************************/ +/******************************* main *******************************/ +/**********************************************************************/ +void +main(argc, argv) +int argc; +char *argv[]; +{ + struct stack_entry { /* stack entry */ + long h, v, w, x, y, z; /* what's on stack */ + }; + short command; /* current command */ + long count[10]; /* the 10 counters at begining of each page*/ + long cpagep = 0; /* current page pointer */ + bool Emitting = FALSE; /* outputting typsetting instructions? */ + int i; /* command parameter; loop index */ + int k; /* temporary parameter */ + char n[STRSIZE]; /* command parameter */ + int PassNo = 0; /* which pass over the DVI page are we on? */ + bool SkipMode = FALSE; /* in skip mode flag */ + int sp = 0; /* stack pointer */ + struct stack_entry stack[STACK_SIZE]; /* stack */ + char SpecialStr[STRSIZE]; /* "\special" strings */ + long val, val2; /* temporarys to hold command information */ + long w = 0; /* current horizontal spacing */ + long x = 0; /* current horizontal spacing */ + long y = 0; /* current vertical spacing */ + long z = 0; /* current vertical spacing */ + + +#ifdef vms + extern noshare int errno; + extern noshare char *sys_errlist[]; +#else + extern char *sys_errlist[]; + extern int errno; +#endif + + setbuf(stderr, NULL); + (void) strcpy(G_progname, argv[0]); + DecodeArgs( argc, argv ); + + power [ 0 ] = 1 ; + for ( i = 1 ; i <= 31 ; i ++) + power [ i ] = power [ i - 1 ] << 1 ; + gpower[0] = 0l ; + for ( i = 1 ; i <= 32 ; i ++) + gpower[i] = gpower[i - 1] + power[i - 1] ; + + if ((i = (int) NoSignExtend(dvifp, 1)) != PRE) { + Fatal( + "%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n", + G_progname); + } + i = (int) SignExtend(dvifp, 1); + if (i != DVIFORMAT) { + Fatal( "%s: DVI format = %d, can only process DVI format %d files\n\n", + G_progname, i, DVIFORMAT); + } + + if (*EmitFileName == '-') + outfp = stdout; + else + if ((outfp = fopen(EmitFileName, WRITE_BINARY)) == NULL) + Fatal("opening output file: fopen(%s) : %s", + EmitFileName,sys_errlist[errno]); + +#ifdef MSDOS + AssureBinary(outfp); +#endif + +#ifdef TIMING +#ifdef BSD_TIME_CALLS + ftime(&timebuffer); + start_time = timebuffer.time + (float)(timebuffer.millitm) / 1000.0; +#else + gettimeofday(&Tp, NULL); + start_time = Tp.tv_sec + ((float)(Tp.tv_usec))/ 1000000.0; +#endif +#endif + + /* it is important that these be the very first things output !!! */ + if ( G_header ) + CopyFile( HeaderFileName ); + + /*****************************/ + /*for( i0=0; i00) +#ifndef vms + EMIT(outfp, "\033&l%hdaE\033&aL", pagesize); +#else + EMIT(outfp, "\033&l%daE\033&aL", pagesize); +#endif + else + EMIT(outfp, "\033&lE\033&aL"); + + if (ncopies>1) +#ifndef vms + EMIT(outfp, "\033&l%hdX", ncopies); +#else + EMIT(outfp, "\033&l%dX", ncopies); +#endif +#endif + if (DoublePage) { + StartPrintPages = PrintPages; +#ifdef IBM3812 + Reverse = (bool)!Reverse; /* perverse and strange */ +#endif + + } + if (Reverse) { +#ifdef DEBUG + if (Debug) + fprintf(stderr, "reverse\n"); +#endif + ReadPostAmble(TRUE); + fseek(dvifp, ppagep, 0); + } else { + ReadPostAmble(TRUE); + fseek(dvifp, 14l, 0); + k = (int) NoSignExtend(dvifp, 1); + GetBytes(dvifp, n, k); + } + PassNo = 0; + + while (TRUE) { + command = (short) NoSignExtend(dvifp, 1) ; +#ifdef DEBUG + if (Debug) + fprintf(stderr,"CMD:\t%d\n", command); +#endif + switch (command) { + case SET1: + case SET2: + case SET3: + case SET4: + val = NoSignExtend(dvifp, (int) command - SET1 + 1); + if (!SkipMode) + SetChar(val, command, PassNo, TRUE,FALSE); + break; + case SET_RULE: + val = NoSignExtend(dvifp, 4); + val2 = NoSignExtend(dvifp, 4); + if (Emitting) + SetRule(val, val2, 1); + break; + case PUT1: + case PUT2: + case PUT3: + case PUT4: + val = NoSignExtend(dvifp, (int) command - PUT1 + 1); + if (!SkipMode) + SetChar(val, command, PassNo, TRUE,FALSE); + break; + case PUT_RULE: + val = NoSignExtend(dvifp, 4); + val2 = NoSignExtend(dvifp, 4); + if (Emitting) + SetRule(val, val2, 0); + break; + case NOP: + break; + case BOP: + cpagep = ftell(dvifp) - 1; + for (i = 0; i <= 9; i++) + count[i] = NoSignExtend(dvifp, 4); + ppagep = NoSignExtend(dvifp, 4); + h = v = w = x = y = z = 0; + hh = vv = 0; + sp = 0; + fontptr = NULL; + prevfont = NULL; + DoBop(); +/* +fprintf(stderr,"skimode %d, count %d, F %d, L %d\n", + (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified); +*/ + SkipMode = (bool) ((FirstPageSpecified && count[0] < FirstPage) || + (LastPageSpecified && count[0] > LastPage )); +/* +fprintf(stderr,"skimode %d, count %d, F %d, L %d\n", + (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified); +*/ + + if (DoublePage && !SkipMode) { + if (PassNo == 0) { + LastPtobePrinted=count[0]; + if (!Reverse && (WouldPrint == 0)) { + if (count[0] == 0l) { + ZeroPage = TRUE; + EvenPage = FALSE; + } + else { + EvenPage = (bool) ( (count[0]<0? labs(count[0])+1: count[0]) %2 == 0); + + if (PrintEmptyPages && EvenPage && PageParity==1) { + WouldPrint ++; + if (PrintFirstPart) { + qfprintf(stderr,"[EvenPage] "); + FormFeed(); + } + } + } + } + WouldPrint ++; +/* + fprintf(stderr, "doublepage %d, page parity = %d, 1=%d 2=%d, Reverse %d, WouldPrint %d, fpZ %d\n", + (int)DoublePage, (int)PageParity,(int)PrintFirstPart,(int)PrintSecondPart, + (int)Reverse, (int)WouldPrint, (int)ZeroPage); +*/ + } + if (!PrintFirstPart && PageParity==1) { + if (count[0]==0l) { + ZeroPage = TRUE; + EvenPage = FALSE; + } + SkipMode = TRUE; + } + else { +/* +fprintf(stderr,"FirstPart\n count %d, mod %d, pp %d\n",(int)count[0],(int)count[0]%2,PageParity); +*/ + SkipMode = (bool)(PageParity != (short)( + (count[0]<0? labs(count[0])+1: count[0])%2)); + if (count[0]==0l) SkipMode=(bool)!SkipMode; + } + + } + Emitting = (bool)((PassNo != 0) && !SkipMode); +/* +fprintf(stderr,"Emitting= %d, PassNo=%d, SkipMode = %d\n",(int)Emitting,(int)PassNo,(int)SkipMode); +*/ + if ( !SkipMode ) { + if ( PassNo == 0) + qfprintf(stderr, "[%ld", count[0]); + } + break; + case EOP: + if ( !SkipMode ) { + if ( PassNo == 0 ) { + /* start second pass on current page */ + fseek(dvifp, cpagep, 0); + PassNo = 1; +#ifdef DEBUG + if (Debug) + fprintf(stderr,"\nStarting second pass\n"); +#endif + + } else { + /* end of second pass, and of page processing */ + + last_ry = UNKNOWN; + FormFeed(); + ++ndone; + + qfprintf(stderr, "] "); + if ( (ndone % 10) == 0 ) + qfprintf(stderr, "\n"); + + if (DoublePage) --PrintPages; + if (--PrintPages < 1) AllDone(TRUE); + PassNo = 0; + } + } else + PassNo = 0; + + if ( PassNo == 0 && Reverse ) { + if ( ppagep > 0 ) + fseek(dvifp, ppagep, 0); + else { + if (DoublePage && !SkipMode) + ZeroPage = (bool)(count[0]==0l); + + if (ZeroPage) + EvenPage = FALSE; + else + EvenPage = (bool) ((int)LastPtobePrinted%2 == 0); + + AllDone(FALSE); + } + } + break; + case PUSH: + if (sp >= STACK_SIZE) + Fatal("stack overflow"); + stack[sp].h = h; + stack[sp].v = v; + stack[sp].w = w; + stack[sp].x = x; + stack[sp].y = y; + stack[sp].z = z; + sp++; + break; + case POP: + --sp; + if (sp < 0) + Fatal("stack underflow"); + h = stack[sp].h; + v = stack[sp].v; + 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: + val = SignExtend(dvifp, (int) command - RIGHT1 + 1); + if (Emitting) + MoveOver(val); + break; + case W0: + if (Emitting) + MoveOver(w); + break; + case W1: + case W2: + case W3: + case W4: + w = SignExtend(dvifp, (int)command - W1 + 1); + if (Emitting) + MoveOver(w); + break; + case X0: + if (Emitting) + MoveOver(x); + break; + case X1: + case X2: + case X3: + case X4: + x = SignExtend(dvifp, (int)command - X1 + 1); + if (Emitting) + MoveOver(x); + break; + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: + val = SignExtend(dvifp, (int)command - DOWN1 + 1); + if (Emitting) + MoveDown(val); + break; + case Y0: + if (Emitting) + MoveDown(y); + break; + case Y1: + case Y2: + case Y3: + case Y4: + y = SignExtend(dvifp, (int)command - Y1 + 1); + if (Emitting) + MoveDown(y); + break; + case Z0: + if (Emitting) + MoveDown(z); + break; + case Z1: + case Z2: + case Z3: + case Z4: + z = SignExtend(dvifp, (int)command - Z1 + 1); + if (Emitting) + MoveDown(z); + break; + case FNT1: + case FNT2: + case FNT3: + case FNT4: + if (!SkipMode) { + SetFntNum(NoSignExtend(dvifp, (int)command -FNT1 +1),Emitting); + } + break; + case XXX1: + case XXX2: + case XXX3: + case XXX4: + k = (int) NoSignExtend(dvifp, (int)command - XXX1 + 1); + GetBytes(dvifp, SpecialStr, k); + if (Emitting) + DoSpecial(SpecialStr, k); + break; + case FNT_DEF1: + case FNT_DEF2: + case FNT_DEF3: + case FNT_DEF4: + k = (int) NoSignExtend(dvifp, (int)command - FNT_DEF1 + 1); + SkipFontDef(); /* SkipFontDef(k); */ + break; + case PRE: + Fatal("PRE occurs within file"); + break; + case POST: + AllDone(FALSE); + PassNo = 0; + break; + case POST_POST: + Fatal("POST_POST with no preceding POST"); + break; + default: + if (command >= FONT_00 && command <= FONT_63) { + if (!SkipMode) + SetFntNum((long) command - FONT_00, Emitting); + } else if (command >= SETC_000 && command <= SETC_127) { + if (!SkipMode) { + SetString(command, PassNo); + } + } else + Fatal("%d is an undefined command", command); + break; + } + } /* while TRUE */ +} + + +/*-->ActualFactor*/ +/**********************************************************************/ +/************************** ActualFactor ****************************/ +/**********************************************************************/ +double /* compute the actual size factor given the approximation */ +ActualFactor(unmodsize) +long unmodsize; /* actually factor * 1000 */ +{ + double realsize; /* the actual magnification factor */ + realsize = (double)unmodsize / 1000.0; + if (abs((int)(unmodsize - 1095l))<2) + realsize = 1.095445115; /*stephalf*/ + else if (abs((int)(unmodsize - 1315l))<2) + realsize = 1.31453414; /*stepihalf*/ + else if (abs((int)(unmodsize - 1577l))<2) + realsize = 1.57744097; /*stepiihalf*/ + else if (abs((int)(unmodsize - 1893l))<2) + realsize = 1.89292916; /*stepiiihalf*/ + else if (abs((int)(unmodsize - 2074l))<2) + realsize = 2.0736; /*stepiv*/ + else if (abs((int)(unmodsize - 2488l))<2) + realsize = 2.48832; /*stepv*/ + else if (abs((int)(unmodsize - 2986l))<2) + realsize = 2.985984; /*stepvi*/ + /* the remaining magnification steps are represented with sufficient + accuracy already */ + return(realsize); +} + + +/*-->AllDone*/ +/**********************************************************************/ +/****************************** AllDone ******************************/ +/**********************************************************************/ +void +AllDone(PFlag) +bool PFlag; +{ + double time; + + if (DoublePage && (PageParity==1)) { /* Shall we go around again?*/ + int k; + char n[STRSIZE]; + + if (PrintEmptyPages && EvenPage && Reverse && PrintFirstPart) { + WouldPrint ++; + qfprintf(stderr,"[EvenPage] "); + FormFeed(); + } +#ifdef LJ + Reverse = (bool)!Reverse; +#endif + if (Reverse) { + if (!PFlag) { + fseek (dvifp, postambleptr, 0); + (void) NoSignExtend(dvifp, 1); + ppagep = NoSignExtend(dvifp, 4); + } + fseek(dvifp, ppagep, 0); + } else { + fseek(dvifp, 14l, 0); + k = (int) NoSignExtend(dvifp, 1); + GetBytes(dvifp, n, k); + } + + if (PrintSecondPart) { + if (PrintFirstPart) { + qfprintf(stderr,"\n----------------------starting second pass\n"); +#ifdef LJ + EMIT(outfp, "\033&l2H"); /* Manual Feed */ +#endif +#ifdef IBM3812 + PMPout(6,"\326\001\305\300\326\252"); + /* set display; ring bell; stop; clear display */ + PMPflush; +#endif + } + + if (PrintEmptyPages && Reverse) { + if (ZeroPage) WouldPrint++; + if ((WouldPrint%2) == 1) { + qfprintf(stderr,"[Padding] "); + FormFeed(); + } + } + WouldPrint = 0; + if (PrintEmptyPages && !Reverse && ZeroPage) { + WouldPrint++; + qfprintf(stderr,"[ZeroPage] "); + FormFeed(); + } + PageParity = 0; + PrintPages = StartPrintPages; + return; + } + } + + if (EvenPage && DoublePage && !Reverse) WouldPrint++; + + if (PrintEmptyPages && DoublePage && PrintSecondPart) { + if (Reverse) { + if (ZeroPage) { + WouldPrint ++; + qfprintf(stderr,"[ZeroPage] "); + FormFeed(); + } + } + else if ((WouldPrint%2) != 0) { + qfprintf(stderr,"[Padding] "); + FormFeed(); + } + } + +#ifdef IBM3812 + PMPout(10, "\373\010PMP.init"); /* re-init printer */ + PMPflush; + + if (used_fontstorage > MAXFONTSTORAGE) { + Warning("\n\7used font_storage of %s: %ld Bytes (of %ld)\7", + PRINTER, used_fontstorage, MAXFONTSTORAGE); + Warning("Try to format file in separate runs!"); + } else + qfprintf(stderr, + "\nAll done, used font_storage of %s: %ld Bytes (of %ld)", + PRINTER, used_fontstorage, MAXFONTSTORAGE); +#endif +#ifdef LJ + qfprintf(stderr, "\nAll done, used font_storage of %s: %ld Bytes", + PRINTER, used_fontstorage); +#ifdef LJ_RESIDENT_FONTS + qfprintf(stderr, " + %d resident font%s", resident_count, + resident_count == 1 ? "" : "s"); +#endif + EMIT(outfp, "\033E"); +#ifdef LJ4 + EMIT(outfp, "\033%%-12345X"); /* what does it? */ +#endif + if (PrintTestPage) EMIT(outfp, "\033z"); +#ifdef vms + /* last record is not flushed to file, unless it is completely filled */ + for (kk = (int)((*outfp)->_cnt); kk > 0; --kk) putc('\0',outfp); + fflush(outfp); +#endif +#endif + + if (!G_quiet) { + fprintf(stderr,"\nDynamically allocated storage: %ld Bytes \n", + allocated_storage); + fprintf(stderr,"%d characters downloaded as soft fonts\n", G_ncdl); + +#ifdef TIMING +#ifdef BSD_TIME_CALLS + ftime(&timebuffer); + time = (timebuffer.time + (float)(timebuffer.millitm)/1000.0) + - start_time; +#else + gettimeofday(&Tp, NULL); + time = (Tp.tv_sec + (float)(Tp.tv_usec)/1000000.0) - start_time; +#endif + + if (ndone > 0) { + fprintf(stderr, + "Time of complete run: %.2f seconds, %d page(s), %.2f seconds/page", + time, ndone, time / ndone); + fprintf(stderr," (%.2f ppm)\n",(ndone * 60) / time); + } + fprintf(stderr,"\n"); +#endif + } + + exit(G_errenc); +} + + +/*-->CopyFile*/ /* copy a file straight through to output */ +/*********************************************************************/ +/***************************** CopyFile ******************************/ +/*********************************************************************/ +void +CopyFile( str ) +char *str; +{ + FILE * spfp; + char t; + if ( (spfp = BINOPEN(str)) == NULL ) { + Warning("Unable to open file %s", str ); + return; + } + qfprintf(stderr," [%s", str); + for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp)) + putc(t, outfp); + fclose(spfp); + qfprintf(stderr,"]"); +} + + +/*-->CopyHPFile*/ /* copy a HP file to output removing unwanted control codes*/ +/*********************************************************************/ +/***************************** CopyHPFile ******************************/ +/*********************************************************************/ +void +CopyHPFile( str ) +char *str; +{ + FILE * spfp; + char t,numstr[20]; + int count,rx,ry,miny,minx,num; + + if ( (spfp = BINOPEN(str)) == NULL ) { + Warning("Unable to open file %s", str ); + return; + } + minx=32767; /* Set to a high value initially */ + miny=32767; + +/* Pass through the input PCL file twice. The first time find the smallest */ +/* x- and y-offsets so that they can be subtracted out when sending */ +/* positioning commands later. The second pass strips the unwanted commands */ +/* from the input file and outputs the rest */ + + qfprintf(stderr," [%s", str); + for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp)) + { + if (t==0x1B) /* Find the escape character */ + { + t=(char) getc(spfp); + if (t==0x2A) /* This indiactes the start of a graphics command */ + { + + t=(char) getc(spfp); + switch(t) + { + case(0x70): + /* These are the graphics positioning commands */ + /* Find the smallest x and y offsets */ + num=0; + count=0; + for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp)) + numstr[count++]=t; + numstr[count]=0; + num= atoi (numstr); + + /* Take into account the possible different ordering */ + /* of the commands (x first, y first) */ + + if ((t==0x59)||(t==0x79)) + { + if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-') + if (num0x60)); t=(char) getc(spfp)); + break; + + case(0x62): + num=0; + count=0; + /* Read in the correct number of bytes of raster graphics */ + /* so that we don't get commands and raster graphics confused */ + + for (t=(char) getc(spfp);((t<0x40)||(t>=0x60));t=(char) getc(spfp)) + numstr[count++]=t; + numstr[count]=0; + if (t==0x4D) + for(t=numstr[count=0];t!=0;t=numstr[++count]); + if (t==0x57) + { + for(t=numstr[count=0];t!=0;t=numstr[++count]); + for(count= atoi(numstr);count>0;count--) + t=(char) getc(spfp); + } + break; + + case(0x63): + for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp)); + break; + + default: + break; + + + } + } + } + } + fclose(spfp); + qfprintf(stderr,"]"); + + if ( (spfp = BINOPEN(str)) == NULL ) { + Warning("Unable to open file %s", str ); + return; + } + qfprintf(stderr," [%s", str); + +/* Pass through the input file again but this time output the */ +/* retained PCL commands */ + + for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp)) + { + if (t==0x1B) + { + t=(char) getc(spfp); + if (t==0x2A) + { + t=(char) getc(spfp); + switch(t) + { + case(0x70): + num=0; + count=0; + for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp)) + numstr[count++]=t; + numstr[count]=0; + num= atoi (numstr); + if ((t==0x59)||(t==0x79)) + { + if (numstr[0]!='+'&&numstr[0]!='-') + { + /* Subtract the minimum offset found in first pass */ + /* and add in the current vertical offset */ + ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset; + /* Output the new positioning command */ + EMIT(outfp,"\033*p%dY",ry); + } + + else if (num>=0) EMIT(outfp,"\033*p%c%dY",numstr[0],num); + else EMIT(outfp,"\033*p%dY",num); + + if (t==0x79) + { + num=0; + count=0; + for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp)) + numstr[count++]=t; /* reconstructed code */ + numstr[count]=0; + num=atoi (numstr); + if(numstr[0]!='+'&&numstr[0]!='-') + { + /*Add in correct horizontal offset */ + rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset; + EMIT(outfp,"\033*p%dX",rx); + } + else if (num>=0) EMIT(outfp,"\033*p%c%dX",numstr[0],num); + else EMIT(outfp,"\033*p%dX",num); + } + } + + if ((t==0x58)||(t==0x78)) + { + if(numstr[0]!='+'&&numstr[0]!='-') + { + /*Add in the correct horizontal offset*/ + rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset; + EMIT(outfp,"\033*p%dX",rx); + } + else if (num>=0) EMIT(outfp,"\033*p%c%dX",numstr[0],num); + else EMIT(outfp,"\033*p%dX",num); + + if (t==0x78) + { + num=0; + count=0; + for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp)) + numstr[count++]=t; + numstr[count]=0; + num= atoi (numstr); + if(numstr[0]!='+'&&numstr[0]!='-') + { + /*Add in correct vertical offset*/ + ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset; + EMIT(outfp,"\033*p%dY",ry); + } + else if (num >=0) EMIT(outfp,"\033*p%c%dY",numstr[0],num); + else EMIT(outfp,"\033*p%dY",num); + } + } + break; + + case(0x74): + /* Set the Raster resolution */ + EMIT(outfp,"\033*t"); + for (t=(char) getc(spfp);t != 0x52; t=(char) getc(spfp)) + putc(t,outfp); + putc(t,outfp); + break; + + case(0x72): + /* Raster Graphics commands such as start */ + EMIT(outfp,"\033*r"); + for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp)) + putc(t,outfp); + putc(t,outfp); + break; + + case(0x62): + /* Transfer the correct number of bytes of raster graphics */ + EMIT(outfp,"\033*b"); + num=0; + count=0; + for (t=(char) getc(spfp);((t<0x40)||(t>=0x60));t=(char) getc(spfp)) + numstr[count++]=t; + numstr[count]=0; + if (t==0x4D) + { + for(t=numstr[count=0];t!=0;t=numstr[++count]) + putc(t,outfp); + EMIT(outfp,"M"); + } + if (t==0x57) + { + for(t=numstr[count=0];t!=0;t=numstr[++count]) + putc(t,outfp); + EMIT(outfp,"W"); + for(count= atoi(numstr);count>0;count--) + { + t=(char) getc(spfp); + putc(t,outfp); + } + } + break; + + case(0x63): + /* Rectangular draw commands */ + EMIT(outfp,"\033*c"); + for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp)) + putc(t,outfp); + putc(t,outfp); + break; + + default: + break; + + + } + } + } + } + fclose(spfp); + qfprintf(stderr,"]"); +} + + + +/*-->DecodeArgs*/ +/*********************************************************************/ +/***************************** DecodeArgs ****************************/ +/*********************************************************************/ +void +DecodeArgs( argc, argv ) +int argc; +char *argv[]; +{ + int argind; /* argument index for flags */ + char curarea[STRSIZE]; /* current file area */ + char curname[STRSIZE]; /* current file name */ + char *tcp, *tcp1; /* temporary character pointers */ + char *this_arg; + double x_offset=0.0, y_offset=0.0; + + if ((tcp = getenv("TEXPXL")) != NULL) + PXLpath = tcp; + +#ifdef LJ_RESIDENT_FONTS + if ((tcp = getenv("TEXFONTS")) != NULL) + TFMpath = tcp; +#endif + + argind = 1; + while (argind < argc) { + tcp = argv[argind]; + if (*tcp == '-') { + ++tcp; + switch (*tcp) { + case 'a': /* a selects different pxl font area */ + PXLpath = ++tcp; + break; +#ifdef IBM3812 + case 'b': /* first page from alternate casette */ + FirstAlternate = TRUE; + break; +#endif + case 'c': /* number of copies to print */ + if ( sscanf(tcp + 1, "%hd", &ncopies) != 1 ) + Fatal("Argument of -c is not a valid integer\n"); + if (ncopies<1) { + Warning("argument of -c < 1; set to 1!"); + ncopies=1; + } + break; +#ifdef DEBUG + case '-': /* d selects Debug output */ + Debug = TRUE; + break; +#endif +#ifdef LJ2P + case 'd': /* d selects DUPLEX mode */ + tcp++; + if (*tcp == '1' ) DuplexMode = 1; + else if (*tcp == '2') DuplexMode = 2; + else { + Warning("Invalid DUPLEX mode, assuming DUPLEX=1, Long-Edge Binding"); + DuplexMode = 1; + } + break; +#endif + case 'D': /* D selects DoublePage */ + DoublePage = TRUE; + tcp++; + if (*tcp == '1' || *tcp == '2') { + if (*tcp == '2') PrintFirstPart = FALSE; + else PrintSecondPart = FALSE; + tcp++; + } + if (*tcp == '-') PrintEmptyPages = FALSE; + break; +#ifdef LJ4 + case 'E': /* do not reset printer (go) */ + econoMode = TRUE; + break; +#endif + case 'e': /* emit file is specified */ + EmitFileName = ++tcp; +#ifdef MSDOS + /* delete trailing ':' (causing hangup) */ + if (EmitFileName[strlen(EmitFileName)-1] == ':') + EmitFileName[strlen(EmitFileName)-1] = '\0'; +#endif +#ifdef OS2 /* repeated to avoid problems with stupid c preprocessors */ + /* delete trailing ':' (causing hangup) */ + if (EmitFileName[strlen(EmitFileName)-1] == ':') + EmitFileName[strlen(EmitFileName)-1] = '\0'; +#endif + break; + case 'f': /* next arg is starting pagenumber */ + if ( sscanf(tcp + 1, "%ld", &FirstPage) != 1 ) + Fatal("Argument is not a valid integer\n"); + FirstPageSpecified = TRUE; + break; +#ifdef LJ + case 'g': /* do not reset printer (go) */ + ResetPrinter = FALSE; + break; +#endif + case 'h': /* copy header file through to output */ + HeaderFileName = ++tcp; + G_header = TRUE; + break; +#if defined(LJ2P) || defined(IBM3812) + case 'l': /* landscape */ + Landscape = TRUE; + break; +#endif +#ifdef MAKETEXPK + case 'M': + /* -M, -M1 => don't make font; -M0 => do. */ + makeTexPK = *(tcp + 1) == '0'; + break; +#endif + case 'x': /* specify x-offset */ + this_arg = 0; + if (!(*++tcp)) { + this_arg = (++argind >= argc ? 0 : argv[argind]); + } else { + this_arg = tcp; + } + if (!this_arg + || sscanf(this_arg,"%lf", &x_offset) != 1) + Fatal("Argument of -x is not a valid floating point number\n"); + break; + case 'y': /* specify y-offset */ + this_arg = 0; + if (!(*++tcp)) { + this_arg = (++argind >= argc ? 0 : argv[argind]); + } else { + this_arg = tcp; + } + if (!this_arg || sscanf(this_arg, "%lf", &y_offset) != 1) + Fatal("Argument of -y is not a valid floating point number\n"); + break; + case 'X': /* specify X-origin in dots */ + this_arg = 0; + if (!(*++tcp)) { + this_arg = (++argind >= argc ? 0 : argv[argind]); + } else { + this_arg = tcp; + } + if (!this_arg || sscanf(this_arg,"%hd", &x_origin) != 1) + Fatal("Argument of -X is not a valid integer\n"); + break; + case 'Y': /* specify Y-origin in dots */ + this_arg = 0; + if (!(*++tcp)) { + this_arg = (++argind >= argc ? 0 : argv[argind]); + } else { + this_arg = tcp; + } + if (!this_arg || + sscanf(this_arg, "%hd", &y_origin) != 1) + Fatal("Argument of -Y is not a valid integer\n"); + break; + case 'm': /* specify magnification to use */ + switch ( (*++tcp) ) { + case '#': + /* next arg is a magnification to use */ + if ( sscanf(tcp + 1, "%ld", &usermag) != 1 ) + Fatal("Argument of mag is not a valid integer\n"); + break; + case '0': + usermag = 1000; + break; + case 'h': + case 'H': + usermag = 1095; + break; + case '1': + usermag = 1200; + break; + case 'q': + usermag = 1250; + break; + case '2': + usermag = 1440; + break; + case '3': + usermag = 1728; + break; + case '4': + usermag = 2074; + break; + case '5': + usermag = 2488; + break; + default: + Fatal("%c is a bad mag step\n", *tcp); + } + break; +#ifdef SUPERCOMMENT + case 'o': /* PostScript command to send */ + if ( ++argind >= argc ) + Fatal("No argument following -o\n", 0); + PScmd[nps++] = argv[argind]; + break; +#endif + case 'p': /* print n pages */ + if ( sscanf(tcp + 1, "%ld", &PrintPages) != 1 ) + Fatal("Argument is not a valid integer\n"); + if (PrintPages < 1) + Fatal("Argument of -p must be greater than 0\n"); + break; + case 'q': /* quiet operation */ + G_quiet = TRUE; + break; + case 'r': /* switch order to process pages */ + Reverse = (bool)(!Reverse); + break; +#ifdef LJ + case 's': /* specify X-origin in dots */ + this_arg = 0; + if (!(*++tcp)) this_arg = (++argind >= argc ? 0 : argv[argind]); + else this_arg = tcp; + if (!this_arg || sscanf(this_arg,"%hd", &pagesize) != 1) + Fatal("Argument of -s is not a valid integer\n"); + switch (pagesize) { + case 1: pgsiz_dots = 3150; break; /* executive */ + case 2: pgsiz_dots = 3300; break; /* letter */ + case 3: pgsiz_dots = 4200; break; /* legal */ + case 26: pgsiz_dots = 3507; break; /* a4 */ + case 80: pgsiz_dots = 2250; break; /* monarc */ + case 81: pgsiz_dots = 2850; break; /* com10 */ + case 90: pgsiz_dots = 2598; break; /* int dl */ + case 91: pgsiz_dots = 2704; break; /* int c5 */ + default: Fatal( +#ifndef vms + "%hd is a bad value for pagesize (1,2,3,26,80,81,90,91)", +#else + "%d is a bad value for pagesize (1,2,3,26,80,81,90,91)", +#endif + pagesize); + } + break; +#endif + case 't': /* ending pagenumber */ + if ( sscanf(tcp + 1, "%ld", &LastPage) != 1 ) + Fatal("Argument is not a valid integer\n"); + LastPageSpecified = TRUE; + break; + case 'v': /* verbatim mode (print pxl-file names) */ + G_noverbatim = FALSE; + break; + case 'w': /* don't print out warnings */ + G_nowarn = TRUE; + break; +#ifdef LJ + case 'z': + PrintTestPage = (bool)(!PrintTestPage); + break; +#endif + default: + fprintf(stderr, "%c is not a legal flag\n", *tcp); + } + } else { + + (void) strcpy(filename, tcp); + tcp = strrchr(argv[argind], '/'); + /* split into directory + file name */ + if (tcp == NULL) { + curarea[0] = '\0'; + tcp = argv[argind]; + } else { + (void) strcpy(curarea, argv[argind]); + curarea[tcp-argv[argind]+1] = '\0'; + tcp += 1; + } + + (void) strcpy(curname, tcp); + /* split into file name + extension */ + tcp1 = strchr(tcp, '.'); + if (tcp1 == NULL) { + (void) strcpy(rootname, curname); + strcat(curname, ".dvi"); + } else { + *tcp1 = '\0'; + (void) strcpy(rootname, curname); + *tcp1 = '.'; + } + + (void) strcpy(filename, curarea); + (void) strcat(filename, curname); + + if ((dvifp = BINOPEN(filename)) == NULL) { + Fatal("%s: can't find DVI file \"%s\"\n\n", + G_progname, filename); + } + } + argind++; + } + + x_goffset = (short) MM_TO_PXL(x_offset) + x_origin; + y_goffset = (short) MM_TO_PXL(y_offset) + y_origin; + + if (dvifp == NULL) { + fprintf(stderr,"\nThis is the DVI to %s converter version %s", + PRINTER, VERSION); +#ifdef SEVENBIT + fprintf(stderr,", 7bit"); +#endif + fprintf(stderr," (%s)\n", OS); + fprintf(stderr,"usage: %s [OPTIONS] dvifile\n", G_progname); + + fprintf(stderr,"OPTIONS are:\n"); +#ifdef DEBUG + fprintf(stderr,"\t-- ..... turns debug output on\n"); +#endif + fprintf(stderr, + "\t-aX ..... X= searchpath leading to pixel-files (.pk or .pxl)\n"); +#ifdef IBM3812 + fprintf(stderr, + "\t-b ..... take paper for first page from alternate casette\n"); +#endif + fprintf(stderr,"\t-cX ..... X= number of copies\n"); +#ifdef LJ2P + fprintf(stderr,"\t-dX ..... duplex, X=1: long-edge, 2: short-edge binding\n"); +#endif + fprintf(stderr,"\t-D ..... turns doublepage output on; "); + fprintf(stderr,"-D1 odd pages only, -D2 even\n"); +#ifdef LJ4 + fprintf(stderr,"\t-E ..... print in econo-mode\n"); +#endif + fprintf(stderr,"\t-eX ..... X= output file\n"); + fprintf(stderr,"\t-fX ..... print from begin of page number X\n"); +#ifdef LJ + fprintf(stderr, + "\t-g ..... do not reset printer at begin of job (go)\n"); +#endif + fprintf(stderr,"\t-hX ..... X= name of headerfile\n"); +#ifdef LJ2P + fprintf(stderr,"\t-l ..... landscape mode\n"); +#endif +#ifdef MAKETEXPK + fprintf(stderr,"\t-MX ..... Don't generate missing PK files\n"); +#endif + fprintf(stderr,"\t-mX ..... magnification X=0;h;1;2;3;4;5;#xxxx\n"); + fprintf(stderr,"\t-pX ..... print X pages\n"); + fprintf(stderr,"\t-q ..... quiet operation\n"); + fprintf(stderr,"\t-r ..... process pages in reverse order\n"); +#ifdef LJ + fprintf(stderr,"\t-sX ..... set paper size to X (see documentation)\n"); +#endif + fprintf(stderr,"\t-tX ..... print to end of page number X\n"); + fprintf(stderr,"\t-w ..... don't print out warnings\n"); + fprintf(stderr,"\t-v ..... tell user which pixel-files are used\n"); + fprintf(stderr,"\t-xX ..... X= x-offset on printout in mm\n"); + fprintf(stderr,"\t-yX ..... X= y-offset on printout in mm\n"); + fprintf(stderr,"\t-XO ..... O= x page origin in dots (default=%d)\n", + XDEFAULTOFF ); + fprintf(stderr,"\t-YO ..... O= y page origin in dots (default=%d)\n", + YDEFAULTOFF ); +#ifdef LJ + fprintf(stderr, + "\t-z ..... print test page with pagecounter after job\n"); +#endif + exit(1); + } + if (EQ(EmitFileName, "")) { + if ((EmitFileName = malloc( STRSIZE )) != NULL) + allocated_storage += STRSIZE; + else + Fatal("Can't allocate storage of %d bytes\n",STRSIZE); + (void) strcpy(EmitFileName, curname); + tcp1 = strchr(EmitFileName, '.'); + *tcp1 = '\0'; + strcat(EmitFileName, EMITFILE_EXTENSION); + } +} + + +/*-->DoConv*/ +/*********************************************************************/ +/******************************** DoConv ***************************/ +/*********************************************************************/ +long +DoConv(num, den, convResolution) +long num, den; +int convResolution; +{ + /*register*/ double conv; + conv = ((double)num / (double)den) * + ((double)mag / 1000.0) * + ((double)convResolution/254000.0); + + return((long) ((1.0/conv)+0.5)); +} + + +/*-->DoSpecial*/ +/*********************************************************************/ +/***************************** DoSpecial ***************************/ +/*********************************************************************/ +typedef enum { None, String, Integer /*, Number, Dimension*/ } + + +ValTyp; +typedef struct { + char *Key; /* the keyword string */ + char *Val; /* the value string */ + ValTyp vt; /* the value type */ + union { /* the decoded value */ + int i; + float n; + } v; +} KeyWord; +typedef struct { + char *Entry; + ValTyp Typ; +} KeyDesc; +#define PSFILE 0 +#define ORIENTATION 1 +#define RESETPOINTS 2 +#define DEFPOINT 3 +#define FILL 4 +#define GRAY 5 +#define PATTERN 6 +#define HPFILE 7 +KeyDesc KeyTab[] = { + { "file", String }, + { "orientation", Integer}, + { "resetpoints", String}, + { "defpoint", String}, + { "fill", String}, + { "gray", Integer}, + { "pattern", Integer}, + { "hpfile", String} + /*, + {"hsize", Dimension}, + {"vsize", Dimension}, + {"hoffset", Dimension}, + {"voffset", Dimension}, + {"hscale", Number}, + {"vscale", Number}*/ + + +}; + + +#define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0])) +void +DoSpecial( str, n ) +/* interpret a \special command, made up of keyword=value pairs */ +char *str; +int n; +{ + char spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE]; + char *sf = NULL; + float x,y; + long x_pos, y_pos; + KeyWord k; + int i, j, j1; + static int GrayScale=10, Pattern=1; + static bool GrayFill=TRUE; + static long p_x[80], p_y[80]; + str[n] = '\0'; + spbuf[0] = '\0'; + + SetPosn(h, v); + while ( (str = GetKeyStr(str, &k)) != NULL ) { + /* get all keyword-value pairs */ + /* for compatibility, single words are taken as file names */ + if ( k.vt == None && access(k.Key, 0) == 0) { + if ( sf ) + Warning("More than one \\special file name given. %s ignored", sf); + (void) strcpy(spbuf, k.Key); + sf = spbuf; +/* + for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++); +*/ + } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 ) + switch (i) { + case PSFILE: + case HPFILE: + if ( sf ) + Warning("More than one \\special file name given. %s ignored", + sf); + (void) strcpy(spbuf, k.Val); + sf = spbuf; +/* + for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++) ; +*/ + break; + case ORIENTATION: +#ifdef IBM3812 + if ((k.v.i >= 0) && (k.v.i < 4)) { + last_ry = UNKNOWN; + sprintf(PMPformat, "\322%c", (unsigned char)k.v.i); + PMPout(2, PMPformat); + if (k.v.i == 1) Landscape = TRUE; + else if (k.v.i == 0) Landscape = FALSE; +#endif +#ifdef LJ + if ((k.v.i >= 0) && (k.v.i < 2)) { + last_ry = UNKNOWN; + EMIT(outfp, "\033&l%dO\033*rF", (unsigned char)k.v.i); +#endif + } else + Warning( "Invalid orientation (%d)given; ignored.", k.v.i); + break; + case RESETPOINTS: + (void) strcpy(spbuf, k.Val); + + sf = NULL; + break; + + case DEFPOINT: + (void) strcpy(spbuf, k.Val); + i=sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys); + if (i>0) { + x_pos=h; y_pos=v; + if (i>1) { + if (sscanf(xs,"%fpt",&x)>0) { + fprintf(stderr,"x = %f\n",x); + x_pos = PT_TO_DVI(x); + } + } + if (i>2) { + if (sscanf(ys,"%fpt",&y)>0) { + fprintf(stderr,"y = %f\n",y); + y_pos = PT_TO_DVI(y); + } + } + p_x[j]=x_pos; + p_y[j]=y_pos; + } else + Warning("invalid point definition\n"); + + sf = NULL; + break; + + case FILL: + (void) strcpy(spbuf, k.Val); + i=sscanf(spbuf,"%d/%d %s",&j,&j1,xs); + if (i>1) { +#ifdef LJ + SetPosn(p_x[j], p_y[j]); + x_pos = (long)PIXROUND(p_x[j1]-p_x[j], hconv); + y_pos = (long)PIXROUND(p_y[j1]-p_y[j], vconv); + if (labs(x_pos)= 0) && (k.v.i < 101)) { + GrayScale = k.v.i; + GrayFill = TRUE; + } else + Warning( "Invalid gray scale (%d) given; ignored.", k.v.i); + break; + case PATTERN: + if ((k.v.i >= 0) && (k.v.i < 7)) { + Pattern = k.v.i; + GrayFill = FALSE; + } else + Warning( "Invalid pattern (%d) given; ignored.", k.v.i); + break; + + default: + Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val); + break; + } + else + Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key); + } + if ( sf ) { + last_ry = UNKNOWN; +#ifdef IBM3812 + PMPflush; +#endif + if (i==HPFILE) + CopyHPFile( sf ); + else + CopyFile( sf ); + } +} + + +/*-->EmitChar*/ +/**********************************************************************/ +/**************************** EmitChar ******************************/ +/**********************************************************************/ +void /* output a character bitmap */ +EmitChar(c, ce) +long c; +struct char_entry *ce; +{ + register int i; + register unsigned char *sl; + unsigned short nbpl, nwpl; + long total; +#ifdef LJ + unsigned char cnv_buffer[10]; +#endif + + +#ifdef LJ +/* +printf("Emit character %c(%d) id=%d, yoff=%d[%d], w=%d[%d], h=%d[%d]\n", + (char)c,(int)c, + fontptr->plusid, + ce->yOffset, fontptr->max_yoff, + ce->width, fontptr->max_width, + ce->height, fontptr->max_height +); +*/ +#endif + + + + if ( fontptr->ncdl == 0 ) { +#ifdef IBM3812 + used_fontstorage += 1028; +#endif +#ifdef LJ + if (fontptr->max_width == 0) { /* we have no realistic values */ + fontptr->max_yoff = CHAR_HEIGTH_LARGE; + fontptr->max_width = CHAR_WIDTH_LARGE; + fontptr->max_height = CHAR_HEIGTH_LARGE*2; + } + + /* open font dict before first char, set active font */ + INT_ASCII(cnv_buffer,fontptr->plusid); +#ifdef LJ4 + EMIT(outfp, "\033*c%sD\033)s68W", cnv_buffer); + EMITB(6, "\0\104\024\2\0\0"); +#else + EMIT(outfp, "\033*c%sD\033)s26W", cnv_buffer); +#ifdef SEVENBIT + EMITB(6, "\0\032\0\1\0\0"); +#else + EMITB(6, "\0\032\0\2\0\0"); +#endif +#endif /* LJ 4 */ + EMITWORD( fontptr->max_yoff); + EMITWORD( fontptr->max_width); + EMITWORD( fontptr->max_height); + EMITB(8, "\0\1\1\25\0\4\0\4"); + EMITB(6, "\0\0\0\0\0\0"); +#ifdef LJ4 + EMITB(22,"\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0"); + EMITB(16," "); + EMITB(4 ,"\2\130\2\130"); +#endif + EMIT(outfp, "\033*c4F"); +#endif + } + if ( fontptr != prevfont ) { /* because this isn't done on pass 0 */ +#ifdef LJ + INT_ASCII(cnv_buffer,fontptr->plusid); + EMIT(outfp, "\033(%sX", cnv_buffer); +#endif + prevfont = fontptr; + } + +#ifdef USEPXL + if (fontptr->id == pk89) { + nwpl = 0; /* initialize variable */ + nbpl = ((int)(ce->width) + 7) >> 3; + total = (long)ce->height * nbpl; + } else if (fontptr->id == id1002) { + nwpl = 0; /* initialize variable */ + nbpl = ((int)(ce->width) + 7) >> 3; + total = (long)ce->height * nbpl; + } else if (fontptr->id == id1001) { + nwpl = ((int)(ce->width) + 31) >> 5; + nbpl = ((int)(ce->width) + 7) >> 3; + total = (long)ce->height * nbpl; + } else { + /* should never be necessary */ + nwpl = 0; + nbpl = 0; + total = 0; + } +#else + nbpl = (num_cols + 7) >> 3; + total = num_rows * nbpl; +#endif +/*************************************************************** + if ( ((char) c == 'i') && (fontptr->plusid == 0)) { + long j; + fprintf(stderr, "cols=%ld, ncols=%ld\n",nwpl,nbpl); + + fprintf(stderr, "%ld Bytes:->",total); + for (j=0; jwhere.address.pixptr); + ic = *(ch+j); + fprintf(stderr,"%X.",ic); + } + fprintf(stderr,"<- Now Emitting\n"); + } +***************************************************************/ +#ifdef USEPXL +#ifdef IBM3812 + if ((short)(ce->height) - ce->yOffset > 55) { + ce->yyOffset = (short) ce->height - ce->yOffset; + ce->yOffset = (short) ce->height; + } else { + ce->yyOffset = (short) 0; + } +#endif +#ifdef LJ + ce->yyOffset = (short) 0; +#endif +#endif + + /* ce->cw = (long)(((double)ce->tfmw / (double)hconv) +0.5); */ + /* set active font to nn, load font pattern xx ... */ +#ifdef IBM3812 + PMPcont(total + 9); +#ifdef USEPXL + sprintf(PMPformat, "\323%c\360%c%c%c", + (unsigned char)fontptr->plusid, + (unsigned char)VisChar((char)c), + (unsigned char)ce->height, + (unsigned char)ce->width); + PMPout(6, PMPformat); + PMPoutC((char)(-(ce->xOffset))); + PMPoutC((char)(ce->cw - (-ce->xOffset + ce->width))); + PMPoutC((char)(ce->yOffset)); +#else + sprintf(PMPformat, "\323%c\360%c%c%c", + (unsigned char)fontptr->plusid, + (unsigned char)VisChar((char)c), + (unsigned char)num_rows, + (unsigned char)num_cols); + PMPout(6, PMPformat); + PMPoutC((char)(-x_offset)); + PMPoutC((char)(ce->cw - (-x_offset + num_cols))); + PMPoutC((char)num_rows-y_offset); +#endif +#endif +#ifdef LJ + INT_ASCII(cnv_buffer,fontptr->plusid); + EMIT(outfp, "\033*c%sd%dE\033(s%ldW", cnv_buffer, + (unsigned int)VisChar((char)c), (long)(total + 16)); + EMITB(4, "\4\0\016\1"); +/* EMITC((char)(Landscape==TRUE)); */ + EMITC((char)0); + EMITC((char)0); +#ifdef USEPXL + EMITWORD(-ce->xOffset); + EMITWORD(ce->yOffset); + EMITWORD(ce->width); + EMITWORD(ce->height); +#else + EMITWORD(-x_offset); + EMITWORD(num_rows-y_offset); + EMITWORD(num_cols); + EMITWORD(num_rows); +#endif + EMITWORD((int)ce->cw * 4); +#endif +#ifdef USEPXL + + if (fontptr->id == pk89) + PkRaster(ce, FALSE); + else if (fontptr->id == id1002) + for (i = 0; i < (int) ce->height; i++) { + sl = ((unsigned char *)(ce->where.address.pixptr) + i * nbpl); + EMITL(nbpl, sl); + } + else if (fontptr->id == id1001) + for (i = 0; i < (int) ce->height; i++) { + sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl); + EMITL(nbpl, sl); + } +#else + for (i = num_rows; i > 0; i--) + { + EMITL (nbpl, bits + (i-1) * nbpl); + } +#endif +#ifdef IBM3812 +#ifdef USEPXL + used_fontstorage += (long)ce->height * ((ce->width + 15) >> 4) + *2 + 14; +#else + used_fontstorage += (long)num_rows * ((num_cols + 15) >> 4) + *2 + 14; +#endif +#endif +#ifdef LJ +#ifdef USEPXL + used_fontstorage += 64 * (((int)((ce->height * ce->width) - 1) / 64) + 1); +#else + used_fontstorage += 64 * ((((num_rows * num_cols) - 1) / 64) + 1); +#endif +#endif + fontptr->ncdl += 1; + G_ncdl += 1; +} + + +/*-->RasterLine*/ +/**********************************************************************/ +/**************************** RasterLine ****************************/ +/**********************************************************************/ +void +RasterLine(ce, nbpl, current_line, buffer) +struct char_entry *ce; +unsigned short nbpl, current_line; +char *buffer; +{ +#ifdef IBM3812 + long total; + static unsigned short maxlines; + + if (current_line == 0) { +#ifdef USEPXL + maxlines = ce->height; + + MoveVert(-ce->yOffset); /* move cursor up */ + MoveHor(-ce->xOffset); /* move cursor right */ +#else + maxlines = num_rows; + + MoveVert(-(num_rows-y_offset)); /* move cursor up */ + MoveHor(-x_offset); /* move cursor right */ +#endif + last_ry = UNKNOWN; /* next time full positioning */ + } + + if (current_line % maxlines == 0) { + if (current_line > 0) { /* maxlines lines have been printed*/ + MoveVert(maxlines); /* move cursor down */ + last_ry = UNKNOWN; /* next time full positioning */ + } +#ifdef USEPXL + total = (long)(ce->height - current_line) * (long)nbpl; +#else + total = (long)(num_rows - current_line) * (long)nbpl; +#endif + if ((total + 9) > 65535) { + maxlines = (unsigned short)((65535 - 9) / nbpl); + total = (long)maxlines * (long)nbpl; + } + + PMPcont(total + 9); + PMPout(2, "\365\0"); + EMITWORD(maxlines); +#ifdef USEPXL + EMITWORD(ce->width); +#else + EMITWORD(num_cols); +#endif + PMPoutC((unsigned char) (total >> 16) & 0xFF); + PMPoutC((unsigned char) (total >> 8 ) & 0xFF); + PMPoutC((unsigned char) total & 0xFF); + } + EMITL((int)nbpl, buffer); +#endif +#ifdef LJ + register int emitbytes; + + for (emitbytes = (int)nbpl; + (*(buffer + emitbytes - 1) == '\0') && (emitbytes > 0); + emitbytes--) ; + EMIT(outfp, "\033*b%dW", emitbytes); + EMITL(emitbytes, buffer); +#endif +} + + +/*-->RasterChar*/ +/**********************************************************************/ +/**************************** RasterChar ****************************/ +/**********************************************************************/ +void /* raster a character bitmap */ +RasterChar(ce) +struct char_entry *ce; +{ + int i; + register unsigned char *sl; + unsigned short nbpl, nwpl; + unsigned char raster_line_buf[BYTES_PER_PIXEL_LINE]; + +#ifdef DEBUG + if (Debug) + fprintf(stderr,"Raster character ...size=%d \n", (int)ce->charsize ); +#endif + +#ifdef USEPXL + if (fontptr->id == pk89) { + nwpl = 0; /* initialize variable */ + nbpl = ((int)(ce->width) + 7) >> 3; + } else if (fontptr->id == id1002) { + nwpl = 0; /* initialize variable */ + nbpl = ((int) ce->width + 7) >> 3; + } else if (fontptr->id == id1001) { + nwpl = ((int) ce->width + 31) >> 5; + nbpl = ((int) ce->width + 7) >> 3; + } else { + /* should never be necessary */ + nwpl = 0; + nbpl = 0; + } +#else + nbpl = (num_cols + 7) >> 3; +#endif + +#ifdef LJ + EMIT(outfp, "\033*t%dR\033*r1A",RESOLUTION); +#endif + { /* read pixel from file */ + if ((ce->charsize == HUGE_SIZE) && (fontptr->id != pk89)) + OpenFontFile(); +#ifdef USEPXL + fseek(pxlfp, ce->where.address.fileOffset, 0); +#else + fseek(gfin, ce->where.address.fileOffset, 0); + gettochar(); + readbits(); +#endif + } + +#ifdef USEPXL + if (fontptr->id == pk89) + PkRaster(ce, TRUE); + else if (fontptr->id == id1002) { + for (i = 0; i < (int) ce->height; i++) { + if (ce->charsize == HUGE_SIZE) { + fread(raster_line_buf, 1, (int) nbpl, pxlfp); + sl = raster_line_buf; + } else + sl = ((unsigned char *)(ce->where.address.pixptr) + + i * nbpl); + + RasterLine(ce, (unsigned int)nbpl, i, sl); + } + } else if (fontptr->id == id1001) { + long filediff; + filediff = (long)nwpl * 4 - nbpl; + for (i = 0; i < (int) ce->height; i++) { + if (ce->charsize == HUGE_SIZE) { + fread(raster_line_buf, 1, (int) nbpl, pxlfp); + /* skip fill bytes */ + fseek(pxlfp, filediff, 1); + sl = raster_line_buf; + } else + sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl); + + RasterLine(ce, (unsigned int)nbpl, i, sl); + } + } +#else + for (i = num_rows; i > 0; i--) + RasterLine(ce, (unsigned int)nbpl, i, bits + (i-1) * nbpl); +#endif +#ifdef LJ + EMIT(outfp, "\033*rB"); +#endif + last_ry = UNKNOWN; +} + + +/*-->Fatal*/ +/**********************************************************************/ +/****************************** Fatal *******************************/ +/**********************************************************************/ +void +Fatal(fmt, a, b, c) /* issue a fatal error message */ +char *fmt; /* format */ +char *a, *b, *c; /* arguments */ +{ + fprintf(stderr, "\n"); + fprintf(stderr, "%s: FATAL--", G_progname); + fprintf(stderr, fmt, a, b, c); + fprintf(stderr, "\n\n"); +#ifndef vms + exit(2); +#else + exit(SS$_ABORT); +#endif +} + + +/*-->FindPostAmblePtr*/ +/**********************************************************************/ +/************************ FindPostAmblePtr **************************/ +/**********************************************************************/ +void +FindPostAmblePtr(postambleptr) +long *postambleptr; +/* this routine will move to the end of the file and find the start + of the postamble */ +{ + long i; + fseek (dvifp, 0l, 2); /* goto end of file */ + *postambleptr = ftell (dvifp) - 4; + fseek (dvifp, *postambleptr, 0); + while (TRUE) { + fseek (dvifp, --(*postambleptr), 0); + if (((i = NoSignExtend(dvifp, 1)) != 223) && + (i != DVIFORMAT)) + Fatal ("Bad end of DVI file"); + if (i == DVIFORMAT) + break; + } + fseek (dvifp, (*postambleptr) - 4, 0); + (*postambleptr) = NoSignExtend(dvifp, 4); + fseek (dvifp, *postambleptr, 0); +} + + +/*-->GetBytes*/ +/**********************************************************************/ +/***************************** GetBytes *****************************/ +/**********************************************************************/ +void +GetBytes(fp, cp, n) /* get n bytes from file fp */ +/*register*/ FILE *fp; /* file pointer */ +register char *cp; /* character pointer */ +int n; /* number of bytes */ +{ + while (n--) + *cp++ = (char)getc(fp); +} + + +/*-->GetFontDef*/ +/**********************************************************************/ +/**************************** GetFontDef *****************************/ +/**********************************************************************/ +void +GetFontDef() +/*********************************************************************** + Read the font definitions as they are in the postamble of the DVI + file. +***********************************************************************/ +{ + unsigned char byte; + while (((byte = (unsigned char) NoSignExtend(dvifp, 1)) >= FNT_DEF1) && + (byte <= FNT_DEF4)) { + switch (byte) { + case FNT_DEF1: + ReadFontDef ( NoSignExtend(dvifp, 1)); + break; + case FNT_DEF2: + ReadFontDef ( NoSignExtend(dvifp, 2)); + break; + case FNT_DEF3: + ReadFontDef ( NoSignExtend(dvifp, 3)); + break; + case FNT_DEF4: + ReadFontDef ( NoSignExtend(dvifp, 4)); + break; + default: + Fatal ("Bad byte value in font defs"); + break; + } + } + if (byte != POST_POST) + Fatal ("POST_POST missing after fontdefs"); +} + + +/*-->GetKeyStr*/ +/**********************************************************************/ +/***************************** GetKeyStr ****************************/ +/**********************************************************************/ +/* extract first keyword-value pair from string (value part may be null) + * return pointer to remainder of string + * return NULL if none found + */ +char KeyStr[STRSIZE]; +char ValStr[STRSIZE]; +char +*GetKeyStr( str, kw ) +char *str; +KeyWord *kw; +{ + char *s, *k, *v, t; + if ( !str ) + return( NULL ); + for ( s = str; *s == ' '; s++) + ; /* skip over blanks */ + if ( *s == '\0' ) + return( NULL ); + for ( k = KeyStr; /* extract keyword portion */ + *s != ' ' && *s != '\0' && *s != '='; + *k++ = *s++) + ; + *k = '\0'; + kw->Key = KeyStr; + kw->Val = v = NULL; + kw->vt = None; + for ( ; *s == ' '; s++) + ; /* skip over blanks */ + if ( *s != '=' ) /* look for "=" */ + return( s ); + for ( s++; *s == ' '; s++); /* skip over blanks */ + if ( *s == '\'' || *s == '\"' ) /* get string delimiter */ + t = *s++; + else + t = ' '; + for ( v = ValStr; /* copy value portion up to delim */ + *s != t && *s != '\0'; + *v++ = *s++) + ; + if ( t != ' ' && *s == t ) + s++; + *v = '\0'; + kw->Val = ValStr; + kw->vt = String; + return( s ); +} + + +/*-->GetKeyVal*/ +/**********************************************************************/ +/***************************** GetKeyVal ****************************/ +/**********************************************************************/ +/* get next keyword-value pair decode value according to table entry */ +bool +GetKeyVal( kw, tab, nt, tno) +KeyWord *kw; +KeyDesc tab[]; +int nt; +int *tno; +{ + int i; + char c = '\0'; + *tno = -1; + for (i = 0; i < nt; i++) + if ( IsSame(kw->Key, tab[i].Entry) ) { + *tno = i; + switch ( tab[i].Typ ) { + case None: + if ( kw->vt != None ) + return( FALSE ); + break; + case String: + if ( kw->vt != String ) + return( FALSE ); + break; + case Integer: + if ( kw->vt != String ) + return( FALSE ); + if ( sscanf(kw->Val, "%d%c", + &(kw->v.i), &c) != 1 + || c != '\0' ) + return( FALSE ); + break; +/* case Number: + * case Dimension: + * if( kw->vt != String ) return( FALSE ); + * if( sscanf(kw->Val,"%f%c", + * &(kw->v.n), &c) != 1 + * || c != '\0' ) return( FALSE ); + * break; + */ + } + kw->vt = tab[i].Typ; + return( TRUE ); + } + return( TRUE ); +} + + + +/*-->IsSame*/ +/**********************************************************************/ +/******************************* IsSame *****************************/ +/**********************************************************************/ +bool /* compare strings, ignore case */ +IsSame(a, b) +char *a, *b; +{ + char *x, *y; + x = a; + y = b; + for ( ; *a != '\0'; a++,b++) + if ( tolower(*a) != tolower(*b) ) + return( FALSE ); + return( *x == *y ? TRUE : FALSE ); +} + + +/*-->NoSignExtend*/ +/**********************************************************************/ +/*************************** NoSignExtend ***************************/ +/**********************************************************************/ +long +NoSignExtend(fp, n) /* return n byte quantity from file fd */ +register FILE *fp; /* file pointer */ +register int n; /* number of bytes */ +{ + long x; /* number being constructed */ + x = 0; + while (n--) { + x <<= 8; + x |= getc(fp); + } + return(x); +} + + +/*-->OpenFontFile*/ +/**********************************************************************/ +/************************** OpenFontFile *****************************/ +/**********************************************************************/ +void +OpenFontFile() +/*********************************************************************** + The original version of this dvi driver reopened the font file each + time the font changed, resulting in an enormous number of relatively + expensive file openings. This version keeps a cache of up to + MAXOPEN open files, so that when a font change is made, the file + pointer, pxlfp, can usually be updated from the cache. When the + file is not found in the cache, it must be opened. In this case, + the next empty slot in the cache is assigned, or if the cache is + full, the least used font file is closed and its slot reassigned for + the new file. Identification of the least used file is based on the + counts of the number of times each file has been "opened" by this + routine. On return, the file pointer is always repositioned to the + beginning of the file. +***********************************************************************/ +{ + int i, least_used, current; + struct pixel_list tmp; + +#ifdef DEBUG + if (Debug) + fprintf(stderr,"open font file %d\n", fontptr->font_file_id); +#endif +/* +fprintf(stderr,"? %lx == %lx\n", pfontptr,fontptr); +*/ + if ((pfontptr == fontptr) && (pxlfp != NO_FILE)) + return; /* we need not have been called */ + + if (fontptr->font_file_id == NO_FILE) + return; /* we need not have been called */ + + tmp = pixel_files[1]; + for (current = 1; + (current <= nopen) && (tmp.pixel_file_id != fontptr->font_file_id); ) { + ++current; + tmp = pixel_files[current]; + } + /* try to find file in open list */ + + if (current <= nopen) /* file already open */ { + if ( (pxlfp = pixel_files[current].pixel_file_id) != NO_FILE ) + fseek(pxlfp, 0l, 0); + /* reposition to start of file */ + } else { + /* file not in open list */ + if (nopen < MAXOPEN) /* just add it to list */ + current = ++nopen; + else { + /* list full -- find least used file, */ + /* close it, and reuse slot for new file */ + least_used = 1; + for (i = 2; i <= MAXOPEN; ++i) + if (pixel_files[least_used].use_count>pixel_files[i].use_count) + least_used = i; + if (pixel_files[least_used].pixel_file_id != NO_FILE) { + FILE * fid; + struct font_entry *fp; + fid = pixel_files[least_used].pixel_file_id; + /* mark file as being closed in the entry */ + fp = hfontptr; + while (fp != NULL && fp->font_file_id != fid) fp = fp->next; + if (fp == NULL) + Fatal("Open file %x not found in font entry list.\n", fid); + else { + fp->font_file_id = NULL; + } + fclose( fid ); + } +#ifdef DEBUG + if (Debug) + fprintf(stderr,"\n__reuse slot %d\n", least_used); +#endif + current = least_used; + } + if ((pxlfp = BINOPEN(fontptr->name)) == NULL) { + Warning("PXL-file %s could not be opened", fontptr->name); + pxlfp = NO_FILE; + } else { +#ifdef DEBUG + if (Debug) fprintf(stderr, + "Opening File <%s> /%x/, Size(font_entry)=%d\n", + fontptr->name, pxlfp, sizeof(struct font_entry )); +#endif + + } + pixel_files[current].pixel_file_id = pxlfp; + pixel_files[current].use_count = 0; + } + pfontptr = fontptr; /* make previous = current font */ + fontptr->font_file_id = pxlfp; /* set file identifier */ + pixel_files[current].use_count++; /* update reference count */ +#ifndef USEPXL + gfin = pxlfp; +#endif +} + + +/*-->PixRound*/ +/**********************************************************************/ +/***************************** PixRound *****************************/ +/**********************************************************************/ +long +PixRound(x, conv) /* return rounded number of pixels */ +long x; /* in DVI units */ +long conv; /* conversion factor */ +{ + return((x + conv) / conv); +} + +#ifdef LJ_RESIDENT_FONTS +/*-->TryResident*/ +/**********************************************************************/ +/**************************** TryResident ***************************/ +/**********************************************************************/ +bool +TryResident(fontptr) +struct font_entry *fontptr; +{ + extern bool tfm_read_info (); + tfm_info_type tfm_info; + + /* To determine if a font is resident, check for a special family + value (header bytes 12..16 in the TFM file). This seems cleaner, + and certainly more convenient, than somehow reading an external + ljfonts.map file in which we'd have to specify information for all + the resident fonts. */ + if (tfm_read_info (fontptr->n, &tfm_info) + && tfm_info.family[0] + && strcmp (tfm_info.family, "HPAUTOTFM") == 0) { + unsigned i; + double factor = fontptr->s / (double) 0x100000; + + resident_count++; + fontptr->resident_p = TRUE; + strcpy (fontptr->symbol_set, tfm_info.coding_scheme); + fontptr->resid = tfm_info.typeface_id; + fontptr->spacing = tfm_info.spacing; + fontptr->style = tfm_info.style; + fontptr->weight = tfm_info.weight; + + if (fontptr->spacing == SPACING_FIXED) { + /* Have to select the point in pitch (characters per inch) instead + of point size, and thus have to figure out the pitch that + corresponds to the point size at which the font is used. + + To do this, take the width of the interword space, and see how + many of those characters will fit in the at size. Then convert + to how many characters will fit in one inch. That's our pitch. + + All the builtin LJ4 fonts that are monospaced are Intellifont, + which have 72.307 points per inch. Not that it really makes any + difference. We don't worry about this elsewhere, since all + point sizes are rounded to .25pt anyway, which is more than the + difference between the various definitions of `point'. */ + double ds_in_points = fontptr->s / 65536.0; + double w_in_points = tfm_info.interword / (double) 0x100000; + if (ds_in_points == 0 || w_in_points == 0) { + /* Avoid division by zero if no interword space. */ + Warning ("%s: Can't determine pitch for this monospaced font.\n", + fontptr->n); + fontptr->pitch = 10; /* Result will look awful, which is good. */ + } else { + fontptr->pitch = 72.307 / (ds_in_points * w_in_points); + } + } + +#ifdef DEBUG + if (Debug) + fprintf(stderr, "%6s: typeface=%u\tspacing=%u\tstyle=%u\tweight=%d\n", + fontptr->n, fontptr->resid, fontptr->spacing, + fontptr->style, fontptr->weight); +#endif + for (i = 0; i < NFNTCHARS; i++) { + struct char_entry *cptr = &(fontptr->ch[i]); + cptr->tfmw = (long) (tfm_info.widths[i] * factor); + cptr->cw = ((fontptr->ch[i].tfmw) / (double) hconv) + .5; + cptr->width = + cptr->height = + cptr->xOffset = + cptr->yOffset = + cptr->yyOffset = 0; + } + return TRUE; + } else { + fontptr->resident_p = FALSE; + + if (tfm_info.family[0] + && strcmp (tfm_info.family, "UNSPECIFIED") == 0) { + Warning("font family for %s is UNSPECIFIED; need to run dvicopy?", + fontptr->n); + fontptr->font_file_id = NO_FILE; + return TRUE; + } else { + return FALSE; + } + } +} +#endif + + + +/*-->ReadFontDef*/ +/**********************************************************************/ +/**************************** ReadFontDef ***************************/ +/**********************************************************************/ +void +ReadFontDef(k) +long k; +{ + long t; + unsigned short i; + struct font_entry *tfontptr; /* temporary font_entry pointer */ + struct char_entry *tcharptr; /* temporary char_entry pointer */ + static int plusid = 0; + bool font_found = FALSE; +#ifdef LJ_RESIDENT_FONTS + bool resident_font_located = FALSE; +#endif +#ifdef LJ + int depth, max_depth; +#endif + +#ifdef DEBUG + if (Debug) + fprintf(stderr,"Mallocating %d Bytes)...\n", + sizeof(struct font_entry )); +#endif + + if ((tfontptr = NEW(struct font_entry )) == NULL) + Fatal("can't malloc space for font_entry"); + + allocated_storage += sizeof(struct font_entry ); + + tfontptr->next = hfontptr; + tfontptr->font_file_id = NULL; + fontptr = hfontptr = tfontptr; + tfontptr->ncdl = 0; + tfontptr->k = k; + tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */ + tfontptr->s = NoSignExtend(dvifp, 4); /* space size */ + tfontptr->d = NoSignExtend(dvifp, 4); /* design size */ + tfontptr->a = (int) NoSignExtend(dvifp, 1); /* length for font name */ + tfontptr->l = (int) NoSignExtend(dvifp, 1); /* device length */ + +#ifdef LJ + tfontptr->max_width = tfontptr->max_height = tfontptr->max_yoff = + max_depth = 0; +#endif + + GetBytes(dvifp, tfontptr->n, tfontptr->a + tfontptr->l); + tfontptr->n[tfontptr->a+tfontptr->l] = '\0'; + + tfontptr->font_mag = (long)(( + ActualFactor((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)) + * ActualFactor(mag) +#ifdef USEPXL + * RESOLUTION * 5.0 +#else + * RESOLUTION +#endif + ) + 0.5); +/* +printf("[%ld]=%lf * %lf * %lf + 0.5 = %ld\n", + ((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)), + ActualFactor((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)), + ActualFactor(mag), + (double)RESOLUTION * 5, + tfontptr->font_mag ); +*/ + +#ifdef LJ_RESIDENT_FONTS + /* Pass in the name; fills in resident_p and resid (if resident). */ + + resident_font_located = (bool) TryResident(tfontptr); + + if (tfontptr->resident_p) + return; + + if (!(resident_font_located)) { +#endif + + if (!(findfile(PXLpath, + tfontptr->n, + tfontptr->font_mag, + tfontptr->name, + FALSE, + 0))) { + Warning(tfontptr->name); /* contains error messsage */ + tfontptr->font_file_id = NO_FILE; + } + else { + font_found = TRUE; + if (!( (G_noverbatim) || (G_quiet) ) ) + fprintf(stderr,"%d: using font <%s>\n", + plusid,tfontptr->name); + } +#ifdef LJ_RESIDENT_FONTS + } +#endif + tfontptr->plusid = plusid; + plusid++; + + /* sprintf(tfontptr->psname,"%s.%ld.%d", + tfontptr->n,tfontptr->font_mag,tfontptr->plusid);*/ + +#ifdef LJ + if (plusid >= HANDLE_MAX_FONTS) + Fatal("can handle only %d fonts! ask a wizzard...\n", + HANDLE_MAX_FONTS); +#endif + if (tfontptr != pfontptr) { + if (font_found) OpenFontFile(); + else + pxlfp = NO_FILE; + } +#ifdef USEPXL + if ( pxlfp == NO_FILE ) { /* allow missing pxl files */ + tfontptr->magnification = 0; + tfontptr->designsize = 0; +#endif + for (i = FIRSTFNTCHAR; i <= LASTFNTCHAR; i++) { + tcharptr = &(tfontptr->ch[i]); +#ifdef USEPXL + tcharptr->width = 0; + tcharptr->height = 0; + tcharptr->xOffset = 0; + tcharptr->yOffset = 0; +#endif + tcharptr->where.isloaded = FALSE; + tcharptr->where.address.fileOffset = NONEXISTANT; + tcharptr->tfmw = 0; + } +#ifdef USEPXL + return; + } + t = (long) NoSignExtend(pxlfp, 1); + if (t == 0) { + t = (long) NoSignExtend(pxlfp, 1); + t = (long) NoSignExtend(pxlfp, 2); + if (t == 1002) + tfontptr->id = id1002; + else if (t == 1001) + tfontptr->id = id1001; + else + Fatal("Unknown Version of PXL-format\n"); + } else { + if (t == PK_PRE) { + unsigned char temp_byte; + temp_byte = (unsigned char) NoSignExtend(pxlfp, 1); + if (temp_byte != PK_ID) Fatal( + "Wrong Version of pk file! (%d should be 89)\n", + (int)temp_byte); + else + tfontptr->id = pk89; + } else + Fatal("unknown font format in file <%s> !\n",fontptr->name); + } + + if ((tfontptr->id == id1002) || (tfontptr->id == id1001)) { + fseek(pxlfp, -20l, 2); + + t = NoSignExtend(pxlfp, 4); + if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t)) + Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX", + tfontptr->name, tfontptr->c, t); + tfontptr->magnification = NoSignExtend(pxlfp, 4); + tfontptr->designsize = NoSignExtend(pxlfp, 4); + + if (tfontptr->id == id1001) + fseek(pxlfp, (long) (NoSignExtend(pxlfp, 4) * 4), 0); + else + fseek(pxlfp, (long) NoSignExtend(pxlfp, 4) , 0); + + for (i = FIRSTFNTCHAR; i <= 127; i++) { /* only defined for 7bit*/ + tcharptr = &(tfontptr->ch[i]); + tcharptr->width = (unsigned short) NoSignExtend(pxlfp, 2); + tcharptr->height = (unsigned short) NoSignExtend(pxlfp, 2); + tcharptr->xOffset = (short) SignExtend(pxlfp, 2); + tcharptr->yOffset = (short) SignExtend(pxlfp, 2); + tcharptr->where.isloaded = FALSE; + if (tfontptr->id == id1001) + tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4) * 4; + else + tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4); + tcharptr->tfmw = (long) + ( (double)(NoSignExtend(pxlfp, 4)) + * (double)tfontptr->s / (double) 0x100000 ); + tcharptr->cw = (long)(((double)tcharptr->tfmw/(double)hconv) + 0.5); + + if (tcharptr->width > CHAR_WIDTH_LARGE || + tcharptr->height > CHAR_HEIGTH_LARGE ) + tcharptr->charsize = LARGE_SIZE; + else + tcharptr->charsize = SMALL_SIZE; +#ifdef LJ + max(tfontptr->max_width,tcharptr->width); + max(tfontptr->max_height,tcharptr->height); + if (tcharptr->yOffset > 0 && (int)tfontptr->max_yoff < (int)tcharptr->yOffset) + tfontptr->max_yoff = tcharptr->yOffset; + if ((depth = tcharptr->height - tcharptr->yOffset)>max_depth) + max_depth = depth; +#endif + + } +#ifdef LJ + tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth : + tfontptr->max_yoff+1; +#endif + } else { /* PK 89 format */ + unsigned char temp_byte; + register unsigned char flag_byte; + long hppp, vppp, pkloc, packet_length; + int car, ii; + + /* read comment */ + for ( ii = temp_byte = (unsigned char) NoSignExtend(pxlfp, 1); + ii>0; ii--) { + flag_byte = (unsigned char) NoSignExtend(pxlfp, 1); +#ifdef DEBUG + if (Debug) fprintf(stderr, "%c", flag_byte ) ; +#endif + } +#ifdef DEBUG + if (Debug) fprintf(stderr, "\n"); +#endif + pkloc = 3 + (int)temp_byte; + tfontptr->designsize = NoSignExtend(pxlfp, 4); + + t = NoSignExtend(pxlfp, 4); + if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t)) + Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX", + tfontptr->name, tfontptr->c, t); + + hppp = NoSignExtend(pxlfp, 4); + vppp = NoSignExtend(pxlfp, 4); + if (hppp != vppp) + Warning("aspect ratio is %ld:%ld (should be 1:1)!", hppp,vppp); + tfontptr->magnification = (long)(hppp * 72.27 * 5 / 65536l + 0.5); + + pkloc += 16; + flag_byte = skip_specials(&pkloc); + + while (flag_byte != PK_POST) { + if ((flag_byte & 7) == 7) { + /* fprintf(stderr,"\nRead long character preamble\n"); */ + + packet_length = (unsigned long)NoSignExtend(pxlfp,4); + if ((car = (int)NoSignExtend(pxlfp, 4)) > (LASTFNTCHAR)) + Fatal("Bad character (%d) in PK-File\n",(int)car) ; + + tcharptr = &(tfontptr->ch[car]); + tcharptr->where.address.fileOffset = pkloc; + /* set pkloc to end_of_packet */ + pkloc += packet_length + 8; + + tcharptr->tfmw = (long) NoSignExtend(pxlfp, 4); + (void) NoSignExtend(pxlfp, 4); /* horesc not used */ + (void) NoSignExtend(pxlfp, 4); /* not used */ + + tcharptr ->width = (unsigned short) NoSignExtend(pxlfp, 4); + tcharptr ->height = (unsigned short) NoSignExtend(pxlfp, 4); + tcharptr ->xOffset = (short) SignExtend(pxlfp, 4); + tcharptr ->yOffset = (short) SignExtend(pxlfp, 4); + tcharptr ->where.isloaded = FALSE; + } else if (flag_byte & 4) { + /* fprintf(stderr,"Read extended short character preamble\n"); */ + + packet_length = ((long) flag_byte & 3) * 65536l + + (unsigned short) NoSignExtend(pxlfp, 2); + if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR)) + Fatal("Bad character (%d) in PK-File\n",(int)car) ; + + tcharptr = &(tfontptr->ch[car]); + tcharptr->where.address.fileOffset = pkloc; + /* set pkloc to end_of_packet */ + pkloc += packet_length + 3; + + tcharptr->tfmw = (long) NoSignExtend(pxlfp, 3); +/* + { register unsigned short t; + t = (unsigned short) NoSignExtend(pxlfp, 1); + tcharptr->tfmw = t * 65536l + + (unsigned short) NoSignExtend(pxlfp, 2); + } +*/ + /* horesc not used */ + (void) NoSignExtend(pxlfp, 2) ; + tcharptr ->width = (unsigned short) NoSignExtend(pxlfp,2); + tcharptr ->height = (unsigned short) NoSignExtend(pxlfp,2); + tcharptr ->xOffset = (short) SignExtend(pxlfp, 2); + tcharptr ->yOffset = (short) SignExtend(pxlfp, 2); + tcharptr ->where.isloaded = FALSE; + } else { + /* fprintf(stderr,"\n"); */ + + packet_length = ((long)flag_byte & 3) * 256 + + NoSignExtend(pxlfp, 1) ; + if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR)) + Fatal("Bad character (%d) in PK-File\n",(int)car) ; + + tcharptr = &(tfontptr->ch[car]); + tcharptr->where.address.fileOffset = pkloc; + /* set pkloc to end_of_packet */ + pkloc += packet_length + 2 ; + + tcharptr->tfmw = (long) NoSignExtend(pxlfp, 3); +/* + { register unsigned short t; + t = (unsigned short) NoSignExtend(pxlfp, 1); + tcharptr->tfmw = t * 65536l + + (unsigned short) NoSignExtend(pxlfp, 2); + } +*/ + /* horesc not used */ + (void) NoSignExtend(pxlfp, 1) ; + tcharptr ->width = (unsigned short) NoSignExtend(pxlfp,1); + tcharptr ->height = (unsigned short) NoSignExtend(pxlfp,1); + tcharptr ->xOffset = (short) SignExtend(pxlfp, 1); + tcharptr ->yOffset = (short) SignExtend(pxlfp, 1); + tcharptr ->where.isloaded = FALSE; + } + + tcharptr->tfmw = (long) + ( tcharptr->tfmw * (double)tfontptr->s / (double) 0x100000 ); + + tcharptr->cw = (long)(((double)tcharptr->tfmw / + (double)hconv) + 0.5); + + if (tcharptr->width > CHAR_WIDTH_LARGE || + tcharptr->height > CHAR_HEIGTH_LARGE ) + tcharptr->charsize = LARGE_SIZE; + else + tcharptr->charsize = SMALL_SIZE; + +#ifdef LJ +/* +printf("char=%d: this=%d, max_width=%d, this=%d,max_height=%d, this=%d,max_yoff=%d\n", + car, tcharptr->width, tfontptr->max_width, + tcharptr->height,tfontptr->max_height, + tcharptr->yOffset,tfontptr->max_yoff); +*/ + max(tfontptr->max_width, tcharptr->width); + max(tfontptr->max_height,tcharptr->height); + if (tcharptr->yOffset > 0 && (int)tfontptr->max_yoff < (int)tcharptr->yOffset) + tfontptr->max_yoff = tcharptr->yOffset; + + if ((depth = tcharptr->height - tcharptr->yOffset) > max_depth) + max_depth = depth; +#endif +/* +fprintf(stderr,"char=%d, yotcharptr=%lx, flag_byte=%d, font=%lx\n",car, tcharptr,flag_byte,tfontptr); +*/ + tcharptr->flag_byte = flag_byte; + fseek(pxlfp, (long) pkloc, 0); + flag_byte = skip_specials(&pkloc); + + } /* end of while */ +#ifdef LJ +tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth : + tfontptr->max_yoff+1; +#endif + +/* +printf("fontid=%d: max_width=%u, max_height=%d, max_yoff=%u\n", + tfontptr->plusid, tfontptr->max_width, + tfontptr->max_height, tfontptr->max_yoff); +*/ + +#else + if ( pxlfp == NO_FILE ) /* allow missing pxl files */ + return; + + gfin = pxlfp; + seekpost(); + readpost(); + if ((tfontptr->c != 0) && (checksum != 0) && (tfontptr->c != checksum)) + Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d", + tfontptr->name, tfontptr->c, checksum); + + for(i=FIRSTFNTCHAR; i<=LASTFNTCHAR; i++) { + if (char_exists[i]) { + tcharptr = &(tfontptr->ch[i]); + tcharptr->tfmw = (long)(((float)tfm_wd[i]*(float)tfontptr->s) / + (float)((long)1l<<20)); + tcharptr->where.address.fileOffset = char_pointer[i]; + } +#ifdef LJ +/* GF USER PLEASE CHECK IF THIS CODE WORKS + tfontptr->max_width = gf_font_max_m; + tfontptr->max_height = gf_font_max_n; + tfontptr->max_yoff = gf_font_min_n; +*/ +#endif +#endif +/*****************************************************************************/ +/*if (tcharptr->charsize==LARGE_SIZE) + fprintf(stderr,"%d:\t <%c> w=%d h=%d xO=%d yO=%d tfmw=%ld cw=%ld %d\n", + i,(char) i, + tcharptr->width,tcharptr->height,tcharptr->xOffset,tcharptr->yOffset, + tcharptr->tfmw, tcharptr->cw, (int)(tcharptr->charsize)); + */ +/*****************************************************************************/ + } + } + + +unsigned char +skip_specials( pkloc ) +long *pkloc; +{ + long i, j; + register unsigned char flag_byte; + do { + flag_byte = (unsigned char) NoSignExtend(pxlfp, 1); +/* +fprintf(stderr,"flagbyte = %d, pkloc=%ld\n",(int)flag_byte,*pkloc); +*/ + + (*pkloc) ++; + if (flag_byte >= 240) + switch (flag_byte) { + case 240: + case 241: + case 242: + case 243 : { + i = 0 ; + for (j = 240; j <= (long)flag_byte; j++) { + i = 256 * i + NoSignExtend(pxlfp, 1) ; + (*pkloc) ++; + } + for (j = 1; j <= i; j++) { + (void) NoSignExtend(pxlfp, 1) ; + (*pkloc) ++; + } + break; + } + case 244 : { + i = NoSignExtend(pxlfp, 4); + (*pkloc) += 4; + break; + } + case 245 : + break; + case 246 : + break ; + case 247: + case 248: + case 249: + case 250: + case 251: + case 252: + case 253: + case 254: + case 255: { + Fatal("Unexpected flagbyte %d!\n", + (int)flag_byte) ; + } + } + } while (!((flag_byte < 240) || (flag_byte == PK_POST))) ; + return(flag_byte); +} + + +/*-->ReadPostAmble*/ +/**********************************************************************/ +/************************** ReadPostAmble ***************************/ +/**********************************************************************/ +/*********************************************************************** + This routine is used to read in the postamble values. It + initializes the magnification and checks the stack height prior to + starting printing the document. +***********************************************************************/ +void +ReadPostAmble(load) +bool load; +{ + FindPostAmblePtr (&postambleptr); + if (NoSignExtend(dvifp, 1) != POST) + Fatal ("POST missing at head of postamble"); +#ifdef DEBUG + if (Debug) + fprintf(stderr,"got POST command\n"); +#endif + ppagep = NoSignExtend(dvifp, 4); + num = NoSignExtend(dvifp, 4); + den = NoSignExtend(dvifp, 4); + mag = NoSignExtend(dvifp, 4); + if ( usermag > 0 && usermag != mag ) + Warning("DVI magnification of %ld over-ridden by user (%ld)", + mag, usermag ); + if ( usermag > 0 ) + mag = usermag; + hconv = DoConv(num, den, hconvRESOLUTION); + vconv = DoConv(num, den, vconvRESOLUTION); + (void) NoSignExtend(dvifp, 4); /* height-plus-depth of tallest page */ + (void) NoSignExtend(dvifp, 4); /* width of widest page */ + if (NoSignExtend(dvifp, 2) >= STACK_SIZE) + Fatal ("Stack size is too small"); + (void) NoSignExtend(dvifp, 2); /* this reads the number of pages in */ + /* the DVI file */ +#ifdef DEBUG + if (Debug) + fprintf(stderr,"now reading font defs"); +#endif + if (load) + GetFontDef (); +} + + +/*-->LoadAChar*/ +/**********************************************************************/ +/***************************** LoadAChar ******************************/ +/**********************************************************************/ +void +LoadAChar(c, ptr) +long c; +register struct char_entry *ptr; +{ + long *pr; + long bytes; + + if (ptr->where.address.fileOffset == NONEXISTANT +#ifdef LJ_RESIDENT_FONTS + || fontptr->resident_p +#endif + ) { + ptr->where.isloaded = FALSE; + return; + } + + OpenFontFile(); + +#ifdef DEBUG + if (Debug) + fprintf(stderr, "LoadAChar: <%c>(%ld) from file at pos %ld\n", + (char)c,c,ptr->where.address.fileOffset); +#endif + +#ifdef USEPXL + + fseek(pxlfp, ptr->where.address.fileOffset, 0); + + if (fontptr->id == pk89) { +#ifdef PARANOIA + unsigned char temp; + temp = (unsigned char) NoSignExtend(pxlfp, 1); + + if ((int)(ptr->flag_byte) != (int)temp) { + fprintf(stderr,"font=%lx, ptr=%lx\n",fontptr,ptr); + Fatal("%d: oh boy! old flag %d, new flag %d, ptr=%lx\n", + (int)c,(int)(ptr->flag_byte),(int)temp,ptr); + } +#endif + + if ((ptr->flag_byte & 7) == 7) { + bytes = ((long) NoSignExtend(pxlfp, 4)) - 28; + fseek(pxlfp, ptr->where.address.fileOffset + 36, 0); +/* +fprintf(stderr,"bytes=%d, seeking at %ld\n", + bytes, ptr->where.address.fileOffset + 36); +*/ + } else if ((ptr->flag_byte & 4) == 4) { + bytes = ((long)ptr->flag_byte & 3) + * 65536l + NoSignExtend(pxlfp, 2) - 13; + fseek(pxlfp, ptr->where.address.fileOffset + 16, 0); + } else { + bytes = ((long)ptr->flag_byte & 3) + * 256 + NoSignExtend(pxlfp, 1) - 8; + fseek(pxlfp, ptr->where.address.fileOffset + 10, 0); + } + } else if (fontptr->id == id1002) + bytes = ((( (long)ptr->width + 7) >> 3) * (long) ptr->height); + else if (fontptr->id == id1001) + bytes = 4 * (((long)ptr->width + 31) >> 5) * (long)ptr->height; + else + bytes = 0; + + if (bytes > 0) { + /* do NOT load Huge characters */ + if ((bytes > HUGE_CHAR_PATTERN) && (fontptr->id != pk89)) { + qfprintf(stderr,"Huge Character <%c> (%ld Bytes)\n", (char)c, bytes); + ptr->charsize = HUGE_SIZE; + ptr->where.isloaded = FALSE; + } else { + if ( (pr = (long *)malloc( bytes )) == NULL ) + Fatal("Unable to allocate %ld bytes for char <%c>\n", + bytes, (char)c); +/* + * else fprintf(stderr,"allocating %ld bytes char <%c>(%d)\t at 0x%lx\n", + * bytes, (char)c,(int)c,pr); + */ +#ifdef DEBUG + if (Debug) + fprintf(stderr, + "Allocating Char <%c>, FileOffset=%lX, Bytes=%ld (%d) <%d>\n", + (char) c, ptr->where.address.fileOffset, bytes, + (int)bytes, (unsigned int)bytes); +#endif + allocated_storage += bytes; + fread(pr, 1, (int) bytes , pxlfp); + ptr->where.address.pixptr = pr; + } + } +#else + fseek(gfin, ptr->where.address.fileOffset, 0); + gettochar(); + readbits(); + if (num_bytes > HUGE_CHAR_PATTERN) + ptr->charsize = HUGE_SIZE; +#endif + ptr->where.isloaded = TRUE; + if (ptr->charsize != SMALL_SIZE +#ifdef LJ + /* we might have problems at the edge of the paper with diff. sized characters + * the correct treatment would be to check whether the bounding box of + * tfontptr is within the paper relative to the current position + */ + || fontptr->max_height > CHAR_HEIGTH_LARGE + || (rasterfont[fontptr->plusid]) +#endif + ) + return; + + EmitChar(c, ptr); +#ifdef USEPXL + /* we should really free the space used by the PXL data after this + point, but it is not large, and besides, we may want to be + more clever in the future, about sending bitmaps. So keep + the data around */ +#endif +} +/*-->SetChar*/ +/**********************************************************************/ +/***************************** SetChar ******************************/ +/**********************************************************************/ +void +SetChar(c, command, PassNo, do_posn,in_string) +long c; +short command; +int PassNo; +bool do_posn,in_string; +{ + register struct char_entry *ptr; /* temporary char_entry pointer */ + bool pos_after = FALSE; + + ptr = &(fontptr->ch[c]); + if (!((ptr->where.isloaded) || (ptr->charsize == HUGE_SIZE))) + LoadAChar(c, ptr); + if (PassNo == 0) + return; + + if (do_posn) { +#ifdef IBM3812 + if (CharStringPos>0) { + fprintf(stderr,"!!!! That should never happen!!!\n"); + CharStringOut; + } +#endif + SetPosn(h, v); + } + +/* +printf("(%d) hh=%ld (+%ld/+%ld), h=%ld, xh=%ld,xhh=%ld, [%ld|%ld] ->%d\n", + (int)do_posn,hh,(long)ptr->cw,(long)ptr->cw*(long)hconv,h, + PIXROUND(h, hconv), + PIXROUND(hh, hconv), + labs((hh-h)),hconv,(labs((hh-h))>hconv) + ); +*/ + + if (in_string && (labs((hh-h))>hconv)) { +#ifdef IBM3812 + CharStringOut; +#endif + SetPosn(h, v); + } + +/* +fprintf(stderr,"raster?=%d - last_ry=%d, last_rx=%d,mmax-height=%d\n", + (int)last_ry < fontptr->max_height, (int)last_ry,(int)last_rx, + (int)fontptr->max_height); +*/ + + if (fontptr->font_file_id != NO_FILE) { /* ignore missing fonts */ + if ( +#ifdef LJ_RESIDENT_FONTS + !fontptr->resident_p && +#endif + (ptr->charsize != SMALL_SIZE +#ifdef LJ + /* the LaserJet cannot print characters + * where the bounding box lies outside the + * paper edge. Missing: right paper edge + */ + || last_ry < (int)fontptr->max_height + || fontptr->max_height > CHAR_HEIGTH_LARGE + || (rasterfont[fontptr->plusid]) +#endif + )) { +#ifdef LJ + int tmp; + char sign; + + if (!do_posn) { + SetPosn(h, v); + } +#ifdef USEPXL + tmp = (int) -ptr->yOffset; +#else + tmp = (int) num_rows-y_offset; +#endif + if (tmp != 0) { + if (tmp < 0) { + sign = '-'; tmp = -tmp; + } else + sign = '+'; + EMIT(outfp, "\033*p%c%dY", sign, tmp); + } +#ifdef USEPXL + tmp = (int) -ptr->xOffset; +#else + tmp = (int) -x_offset; +#endif + if (tmp != 0) { + if (tmp < 0) { + sign = '-'; tmp = -tmp; + } else + sign = '+'; + EMIT(outfp, "\033*p%c%dX", sign, tmp); + } +#endif +#ifdef IBM3812 + CharStringOut; +#endif +#ifdef DEBUG + if (Debug) +#ifndef vms + fprintf(stderr,"Raster character <%c> %hd\n", (char) c,(short)c); +#else + fprintf(stderr,"Raster character <%c> %d\n", (char) c,(short)c); +#endif +#endif + RasterChar(ptr); + pos_after = TRUE; + } else { + unsigned char cc; + cc = VisChar((char)c); +#ifdef IBM3812 +#ifdef USEPXL + if ( ptr->yyOffset || (!in_string) ) { + CharStringOut; + MoveVert(ptr->yyOffset); + sprintf(PMPformat, "\01%c", cc); + PMPout(2, PMPformat); + MoveVert((int)-(ptr->yyOffset)); + } else { +#endif + if (CharStringPos==CHARSTRINGMAX) + CharStringOut; + + CharString[CharStringPos] = cc; + CharStringPos++; +#ifdef USEPXL + } +#endif +#endif +#ifdef LJ +#define TRANSPARENTCHAR(ch) \ + if ((ch == 0l) || (ch >= 7l && ch <= 15l) || (ch == 27l)) \ + EMIT(outfp, "\033&p1X%c", (unsigned char)ch); \ + else EMITC((unsigned char)ch) +#ifdef USEPXL + if (ptr->yyOffset) { +#ifndef vms + EMIT(outfp, "\033*p+%hdY", ptr->yyOffset); + TRANSPARENTCHAR(cc); + EMIT(outfp, "\033*p-%hdY", ptr->yyOffset); /* GUGUGU 255 */ +#else + EMIT(outfp, "\033*p+%dY", ptr->yyOffset); + TRANSPARENTCHAR(cc); + EMIT(outfp, "\033*p-%dY", ptr->yyOffset); /* GUGUGU 255 */ +#endif + } else +#endif +/* EMITC( (unsigned char)c);*/ + { TRANSPARENTCHAR(cc);} +#endif + } + hh += (long) ptr->cw*hconv; + } + if (command <= SET4) + h += ptr->tfmw; + if (pos_after) { + SetPosn(h, v); + } +} + + +void +DoBop() +{ + struct font_entry *p; +#ifdef LJ + register short i; + if (fonts_used_on_this_page > MAX_FONTS_PER_PAGE) { + for (i = 0; i < HANDLE_MAX_FONTS; i++) + rasterfont[i] = FALSE; + } + fonts_used_on_this_page = 0; +#endif + for (p = hfontptr; p; p = p->next) { + p->used_on_this_page = FALSE; + } +} + + +/*-->SetFntNum*/ +/**********************************************************************/ +/**************************** SetFntNum *****************************/ +/**********************************************************************/ +void +SetFntNum(k, Emitting) +long k; +bool Emitting; +/* this routine is used to specify the font to be used in printing future + characters */ +{ +#ifdef LJ + static unsigned short plusid = 0; +#endif + fontptr = hfontptr; + while ((fontptr != NULL) && (fontptr->k != k)) + fontptr = fontptr->next; + if (fontptr == NULL) + Fatal("font %ld undefined", k); + if (Emitting && fontptr->font_file_id != NO_FILE) { + if (!fontptr->used_on_this_page +#ifdef LJ_RESIDENT_FONTS + && !fontptr->resident_p +#endif + ) { + fontptr->used_on_this_page = TRUE; +#ifdef LJ + if (++fonts_used_on_this_page > MAX_FONTS_PER_PAGE) { + qfprintf(stderr,"this is the %d. font on this page!", + fonts_used_on_this_page); + qfprintf(stderr," (max = %d) rastering characters!\n", + MAX_FONTS_PER_PAGE); + rasterfont[fontptr->plusid] = TRUE; + } +#endif + } +#ifdef DEBUG + if (Debug) + fprintf(stderr, "Switching to font #%d (%s).\n", k, fontptr->n); +#endif + /* activate font */ +#ifdef IBM3812 + sprintf(PMPformat, "\323%c", (unsigned char)fontptr->plusid); + PMPout(2, PMPformat); +#endif +#ifdef LJ + if (!rasterfont[fontptr->plusid]) { +#ifdef LJ_RESIDENT_FONTS + if (fontptr->resident_p) { +#ifdef DEBUG + if (Debug) + fprintf(stderr, "Resident font #%d.\n", fontptr->resid); +#endif + EMIT(outfp, "\033(%s", fontptr->symbol_set); + EMIT(outfp, "\033(s%up%.2f%c%us%db%uT", + fontptr->spacing, + /* height in points, or pitch */ + fontptr->spacing ? fontptr->s / 65536.0 + : fontptr->pitch , + fontptr->spacing ? 'v' : 'h', /* height or pitch? */ + fontptr->style, /* upright, italic, ... */ + fontptr->weight, /* regular, bold, ... */ + fontptr->resid); + } else +#endif /* LJ_RESIDENT_FONTS */ + if (fontptr->plusid>0) EMIT(outfp, "\033(%dX", fontptr->plusid); + else EMIT(outfp, "\033(X"); + } +/* else fprintf(stderr,"I am doing rasterfont for plusid=%d instead\n", + fontptr->plusid); +*/ +#endif + } +#ifdef LJ /* reassignment of printer font id 0.48 */ + else if (fontptr->font_file_id != NO_FILE +#ifdef LJ_RESIDENT_FONTS + && !fontptr->resident_p +#endif + ) { + if (fontptr->ncdl == 0) { +#ifdef DEBUG + if (Debug) + fprintf(stderr, "Changing plusid from %d to %d\n", + fontptr->plusid, (int)plusid); +#endif + fontptr -> plusid = plusid; + plusid ++; + } + } +#endif +} + + +/*-->SetPosn*/ +/**********************************************************************/ +/***************************** SetPosn ******************************/ +/**********************************************************************/ +void /* output a positioning command */ +SetPosn(x, y) +long x, y; +{ + int rx, ry; + rx = (int)PIXROUND(x, hconv) + x_goffset; + ry = (int)PIXROUND(y, vconv) + y_goffset; + +/* +* fprintf(stderr,"setposn to %ld/%ld, %d/%d\n",x,y,rx,ry); +*/ + +#ifdef IBM3812 + PMPcont(3); + PMPoutC('\340'); + EMITWORD(LARGER(rx,0)); + + if (last_ry != ry) { /* necessary to set new y-position */ + PMPcont(3); + PMPoutC('\341'); + EMITWORD(LARGER(ry,0)); + } +#endif +#ifdef LJ + if (last_ry != ry) /* necessary to set new y-position */ + EMIT(outfp, "\033*p%dx%dY", LARGER(rx,0), LARGER(ry,0)); + else + EMIT(outfp, "\033*p%dX", LARGER(rx,0)); +#endif + + last_ry = ry; /* last y-position on output device */ + last_rx = rx; /* last x-position on output device */ +/* + * must know where device "really" is horizontally, for rel. posning. + * (maybe in the future), but we always use direct positioning for + * vertical movement. + */ + /* hh = rx * hconv; */ + hh = x; + vv = y; +/* + * fprintf(stderr,"DoPosn: x=%ld, y=%ld, rx=%d, ry=%d, hh=%ld, vv=%ld\n", + * x,y,rx,ry,hh,vv); + */ +} + + +#ifdef IBM3812 +/*-->PMPLine*/ +/**********************************************************************/ +/***************************** PMPLine ******************************/ +/**********************************************************************/ +void /* drawing lines on the 3812 using PMP vector commands */ +PMPLine(w, y, x) +int w, y, x; +{ + + if ((w == 0) || ((x == 0) && (y == 0))) + return; + +/* +fprintf(stderr,"w=%d / %d - %d, y=%d / %d - %d, x=%d / %d - %d\n", + w,(char)(w & 0xff),(int)((signed_char)(w & 0xff)), + y,(char)(y & 0xff),(int)((signed_char)(y & 0xff)), + x,(char)(x & 0xff),(int)((signed_char)(x & 0xff))); +*/ + + if ( (((signed_char)(x & 0xff)) == x ) && + ( ((signed_char)(y & 0xff)) == y ) ) { + PMPcont(6); + PMPout(1, "\370"); + EMITWORD(3); /* length of vector */ + PMPoutC((unsigned char)(0x80 | 0x00 | (unsigned char) w)); + PMPoutC((signed_char)(y & 0xff)); + PMPoutC((signed_char)(x & 0xff)); +/* + fprintf(stderr,"F8 00 03: w=%d, x=%d(%d-%.2X), y=%d(%d-%.2X),\n", + w,x,(char)(x & 0xff),(signed_char)(x & 0xff), + y,(char)(y & 0xff),(signed_char)(y & 0xff)); +*/ + + } else { + PMPcont(8); + PMPout(1, "\370"); + EMITWORD(4 + 1); /* length of vector */ + PMPoutC((unsigned char)(0xC0 | 0x00 | (unsigned char) w)); + EMITWORD(y); + EMITWORD(x); +/* + fprintf(stderr,"F8 00 05: w=%d, x=%d, y=%d,\n", w,x,y); +*/ + } +} + + +#endif +/*-->SetRule*/ +/**********************************************************************/ +/***************************** SetRule ******************************/ +/**********************************************************************/ +void /* this routine will draw a rule */ +SetRule(a, b, Set) +long a, b; +int Set; +{ + long xx, yy; +#ifdef IBM3812 + short hor_offset, vert_offset, ll; +#endif + if ( a > 0 && b > 0 ) { + SetPosn(h, v); /* lower left corner */ + xx = (long)PIXROUND(b, hconv); /* width */ + yy = (long)PIXROUND(a, vconv); /* height */ + +#ifdef DEBUG + if (Debug) + fprintf(stderr,"Rule xx=%ld, yy=%ld\n", xx, yy); +#endif + +#ifdef IBM3812 + hor_offset = (short)(last_ry - yy); + if (hor_offset < 0) yy += hor_offset; + if (last_rx < 0) xx += last_rx; + + if (Landscape) { + if (last_ry > MAX_PAGE_WIDTH) yy += MAX_PAGE_WIDTH-last_ry; + hor_offset = (short)(MAX_PAGE_HEIGHT - (last_rx + xx)); + } else { + if (last_ry > MAX_PAGE_HEIGHT) yy += MAX_PAGE_HEIGHT-last_ry; + hor_offset = (short)(MAX_PAGE_WIDTH - (last_rx + xx)); + } + if (hor_offset < 0) xx += hor_offset; + + if ((xx > 31) && (yy > 31)) { +/* + * fill area by multiple lines (kind of a mess) + * process for simplicity always horizontally + */ + +/* fprintf(stderr, "large box: w=%d, x=%d, y=%d\n",(int)yy,(int)xx,0);*/ + + hor_offset = HOR_HALF(30); + MoveHor(hor_offset); + vert_offset = VERT_HALF(30); + MoveVert(-vert_offset); + ll = (short)xx - 30; + + for (; yy > 30; yy -= 30) { + PMPLine(30, 0, ll); + MoveHor(-ll); + MoveVert(-30); + } + + hor_offset = -hor_offset + HOR_HALF(yy); + MoveHor(hor_offset); + vert_offset = (vert_offset - 30) + VERT_HALF(yy); + MoveVert(-vert_offset); + + PMPLine((int)yy, 0, (int)(xx - yy)); + + } else if ( (yy < xx) && (xx > 0) ) { + +/* fprintf(stderr, "hori rule: w=%d, x=%d, y=%d\n",(int)yy,(int)(xx-yy),0);*/ + + hor_offset = HOR_HALF(yy); + vert_offset = VERT_HALF(yy); + + MoveHor(hor_offset); + MoveVert(-vert_offset); + + PMPLine((int)yy, 0, (int)(xx - yy)); + } else if ( (xx < yy) && (yy > 0)) { + + hor_offset = HOR_HALF(xx); + vert_offset = VERT_HALF(xx); +/* + fprintf(stderr, "move: x=%d, y=%d\n",hor_offset,-vert_offset); + fprintf(stderr, "vert rule: w=%d, x=%d, y=%d\n",(int)xx,0,(int)-(yy-xx)); +*/ + MoveHor(hor_offset); + MoveVert(-vert_offset); + + PMPLine((int)xx, (int)-(yy - xx), 0); + } else if (xx == yy) { + short y0; /* small square box!! */ + + y0 = (short)yy / 2; + hor_offset = HOR_HALF(y0); + MoveHor(hor_offset); + vert_offset = VERT_HALF(y0); + MoveVert(-vert_offset); + ll = (short)xx - y0; + + PMPLine((int)y0, 0, ll); + + hor_offset = -(ll + hor_offset); + vert_offset = (y0 - vert_offset); + + yy -= (long)y0; + hor_offset += HOR_HALF(yy); + MoveHor(hor_offset); + vert_offset += VERT_HALF(yy); + MoveVert(-vert_offset); + + PMPLine((int)yy, 0, (int)xx - yy); + } +#endif +#ifdef LJ + if (last_ry + 1 < yy) yy = last_ry + 1; + if (last_rx < 0) xx += last_rx; + + if (((int)pgsiz_dots >0) && ((int)last_ry > (int)pgsiz_dots)) + yy += (long)pgsiz_dots - (long)last_ry; + + if ((yy>0) && (xx>0)) + EMIT(outfp, "\033*p-%ldY\033*c%lda%ldbP", yy - 1, xx, yy); +#endif + last_ry = UNKNOWN; /* next time full positioning */ + } + if (Set) + h += b; +} + + +/*-->SetString*/ +/**********************************************************************/ +/***************************** SetString ****************************/ +/**********************************************************************/ +void +SetString(firstch, PassNo) /* read and set a consecutive string of chars */ +short firstch; +int PassNo; +{ + short c; + register unsigned short i; + +#ifdef DEBUG + if (Debug) + fprintf(stderr, "SetString "); +#endif + for (i = 0, c = firstch; c >= SETC_000 && c <= SETC_127; i++) { +#ifdef DEBUG + if (Debug) + fprintf(stderr, "%d(%c) ", c, c); +#endif + SetChar((long)c, c, PassNo, (bool)(i==0),TRUE); + c = (short) NoSignExtend(dvifp, 1); + } + fseek(dvifp, -1l, 1); /* backup one character */ +#ifdef IBM3812 + CharStringOut; +#endif +#ifdef DEBUG + if (Debug) + fprintf(stderr, "...SetString\n"); +#endif +} + +#ifndef ARITHMETIC_RIGHT_SHIFT +long signTab[5] = {0,0x00000080,0x00008000,0x00800000,0x00000000}; +long extendTab[5] = {0,~0^0xff,~0^0xffff,~0^0xffffff,~0^0xffffffff}; +#endif + +/*-->SignExtend*/ +/**********************************************************************/ +/**************************** SignExtend ****************************/ +/**********************************************************************/ +long +SignExtend(fp, n) /* return n byte quantity from file fd */ +register FILE *fp; /* file pointer */ +register int n; /* number of bytes */ +{ + int n1; /* number of bytes */ + long x; /* number being constructed */ +#ifdef SIGN_DEBUG + long x0; /* copy of x */ +#endif + x = getc(fp); /* get first (high-order) byte */ + n1 = n--; + while (n--) { + x <<= 8; + x |= getc(fp); + } +/* + * NOTE: This code assumes that the right-shift is an arithmetic, rather + * than logical, shift which will propagate the sign bit right. According + * to Kernighan and Ritchie, this is compiler dependent! + */ + +#ifdef SIGN_DEBUG + x0 = x; +#endif + +#ifdef ARITHMETIC_RIGHT_SHIFT + x <<= 32 - 8 * n1; + x >>= 32 - 8 * n1; /* sign extend */ +#else + if (x & signTab[n1]) x |= extendTab[n1]; +#endif + +#ifdef SIGN_DEBUG + fprintf(stderr,"\tSignExtend(fp,%d)=%X, was=%X,%d\n", + n1,x,x0,x0&signTab[n1]); +#endif + +#ifdef DEBUG + if (Debug > 1) + fprintf(stderr,"\tSignExtend(fp,%d)=%X\n", n1, x); +#endif + return(x); +} + + +/*-->SkipFontDef*/ +/**********************************************************************/ +/**************************** SkipFontDef ***************************/ +/**********************************************************************/ +void +SkipFontDef() +{ + int a, l; + char n[STRSIZE]; + + (void) NoSignExtend(dvifp, 4); + (void) NoSignExtend(dvifp, 4); + (void) NoSignExtend(dvifp, 4); + a = (int) NoSignExtend(dvifp, 1); + l = (int) NoSignExtend(dvifp, 1); + GetBytes(dvifp, n, a + l); +} + + +/*-->Warning*/ +/**********************************************************************/ +/***************************** Warning ******************************/ +/**********************************************************************/ +void /* issue a warning */ +Warning(fmt, a, b, c, d) +char *fmt; /* format */ +char *a, *b, *c, *d; /* arguments */ +{ +#ifndef vms + G_errenc = 1; +#else + G_errenc = (SS$_ABORT | STS$M_INHIB_MSG); /* no message on screen */ +#endif + if ( G_nowarn || G_quiet ) + return; + + fprintf(stderr, "warning : "); + fprintf(stderr, fmt, a, b, c, d); + fprintf(stderr, "\n"); +} + +void +PutWord(w) +int w; +{ + EMITC((char)(w >> 8) & 0xff); + EMITC((char)w & 0xff); +} + + +#ifdef IBM3812 +/*-->PMPout*/ +/*****************************************************************************/ +/* This routine produces the PMP-envelopes for the 3812. Its semantics are: + + first arg == 0 ... flush buffer + first arg == -1 ... number of bytes specified in the second argument + have to be continuous, that is they must not + be disrupted by ENTER PMP etc. + first arg > 0 output first arg bytes + + If arg2 > OUTBUFSIZE ... flush buffer, + switch to unbuffered mode + (dont't collect PMP commands) + If arg2+bufferpointer > OUTBUFSIZE ... flush buffer, + block will fit into buffer + otherwise ..... block will fit into buffer + + Buffering is done to reduce the ENTER PMP-commands. Initially + the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is + necessary to enter PMP mode. The ENTER-PMP-command contains the + number of bytes that will be interpreted as PMP-commands. In the + most naive approach for each primitive command (eg. set cursor) you + have to produce a seperate ENTER-PMP-envelope (5 bytes). It is + favourable to collect as many PMP commands as possible in one envelope. */ +/*****************************************************************************/ +void +PMPout(l, s) +char *s; +int l; +{ + static char buffer[OUTBUFSIZE]; + static unsigned short bp = 0; /* range 0..OUTBUFSIZE */ + static long continuous = 0l; + static bool buffered = TRUE; + + if (l == 0) { + if (bp == 0) + return; + EMIT(outfp, "\033[C%c%c", (unsigned char)(bp & 0xFF), + (unsigned char)(bp >> 8)); + EMITB((int)bp, buffer); + bp = 0; + return; + } + if (l == -1) { + continuous = (long)s; + if (continuous + (long)bp + 5l > (long) OUTBUFSIZE) + PMPflush; + buffered = (bool) ((continuous + 5l <= (long) OUTBUFSIZE)); + if (!buffered) { + EMIT(outfp, "\033[C%c%c", + (unsigned char)(continuous & 0xFF), + (unsigned char)((continuous >> 8) & 0xFF)); + } + return; + } + if (buffered) { + register int i; + if ( ((long)l + bp) > OUTBUFSIZE) + PMPflush; + for (i = 0; i < l; i++) + buffer[bp+i] = s[i]; + bp += (unsigned short)l; + } else { + EMITB((int)l, s); + buffered = (bool) ((continuous -= (long)l) <= 0) ; + } +} + + +void +PMPoutC(c) +char (c); +{ + PMPout(1, &c); +} + + +#endif +#ifdef MSDOS +/*-->AssureBinary*/ +/**********************************************************************/ +/*************************** AssureBinary *****************************/ +/**********************************************************************/ +/* This procedure is both DOS AND MSC dependent. The MSC file open on */ +/* a device ignores the 'binary' of the "wb" parameter and opens the */ +/* file in ascii mode. This procedure sets the file f to binary mode */ +/* if it is connected to a device that is not console input or output */ +/* or the null device. For other operating systems this routine is */ +/* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */ +/**********************************************************************/ +void +AssureBinary(f) +FILE *f; +{ + union REGS regs; /* registers for bios call */ + + regs.h.ah = (unsigned char) 0x44; /* IOCTL */ + regs.h.al = (unsigned char) 0x00; /* get device information */ + regs.x.bx = (unsigned int) fileno(f); /* handle from MSC */ + intdos(®s, ®s); /* call DOS interrupt */ + /* ---> result in DX */ + + if ( (regs.h.dl & 0x80) /* file handle points to a device */ + && !(regs.h.dl & 0x07) ) /* neither console i/o or null */ { + + regs.h.dl |= 0x20; /* set BINARY bit in device info */ + + regs.h.ah = (unsigned char) 0x44; /* IOCTL */ + regs.h.al = (unsigned char) 0x01; /* set device information*/ + regs.x.bx = (unsigned int) fileno(f); /* handle from MSC */ + regs.h.dh = (unsigned char) 0x00; /* clear DH */ + intdos(®s, ®s); /* call DOS interrupt */ + } +} + + +#endif + +#ifdef USEPXL +bool getbit (); +unsigned char getnyb (); +long pk_packed_num (); + + +#define PKBYTE *pkloc; pkloc ++ +#define OUTCHAR(c) raster_line_buf[bp]= (unsigned char)c; bp++ + +unsigned char bitweight, inputbyte ; +unsigned char dyn_f ; +unsigned char *pkloc; +int repeatcount; + +void /* */ +PkRaster(ce, raster) +struct char_entry *ce; +bool raster; +{ + int rp; + int current_line; + int wordwidth ; + bool turnon; + unsigned short nbpl; + long rowsleft, word, wordweight, hbit, count, i, j, tl; + long row[101] ; + unsigned char raster_line_buf[BYTES_PER_PIXEL_LINE]; + unsigned short bp; + + + if (ce->charsize == HUGE_SIZE) + Fatal( "cannot process currently PK font patterns of that size!\n"); + + + current_line = 0; + pkloc = (unsigned char *)ce->where.address.pixptr; + dyn_f = (unsigned char)(ce->flag_byte >> 4); + turnon = (bool)((ce->flag_byte & 8) == 8); + wordwidth = (int)(ce->width + 31) >> 5 ; + nbpl = ((int)(ce->width) + 7) >> 3; + + bitweight = 0 ; + if (dyn_f == 14) { + /*printf("\n");*/ + for (i = 1; i <= (long)ce->height; i++) { + word = 0 ; + wordweight = 31 ; + bp = 0; /* Sowa */ + +#ifdef DRAWGLYPH + printf(" |"); +#endif + for (j = 1; j <= (long) ce->width; j++) { + bool getbit; + /* bp = 0; SOWA */ +/*******************************************begin Getbit *********/ + bitweight /= 2 ; + if ( bitweight == 0 ) { + inputbyte = PKBYTE ; + bitweight = 128 ; + } + getbit = (bool) + ( inputbyte >= bitweight ) ; + if ( getbit ) + inputbyte -= bitweight ; +/*********************************************end Getbit *********/ + + if (getbit) + word += power[wordweight] ; + + wordweight --; + if (wordweight == -1) { + +#ifdef DRAWGLYPH + { int k; + for (k=31; k>=0; k--) { + if ((power[k] & word)!=0) printf("M"); + else printf("."); + } + } +#endif + + OUTCHAR((word >> 24 & 0xFF)); + OUTCHAR((word >> 16 & 0xFF)); + OUTCHAR((word >> 8 & 0xFF)); + OUTCHAR((word & 0xFF)); + + word = 0 ; + wordweight = 31 ; + } + } + if (wordweight < 31) { +#ifdef COMMENT +#ifdef DRAWGLYPH + { int k; + for (k=15; k>=0; k--) { + if ((power[k] & word)!=0) printf("Z"); + else printf(":"); + } + } + printf("|\n ----|"); +#endif +#endif + + for (j = 3; j >= (wordwidth * 4 - (long)nbpl); + j--) { + + OUTCHAR(((word >> (j << 3)) & 0xff)); + +#ifdef DRAWGLYPH + { int k; + for (k=7; k>=0; k--) { + if ((power[k] & ((word >> (j << 3)) & 0xff))!=0) printf("M"); + else printf("."); + } + } +#endif + + } + } + + if (raster) { + RasterLine(ce, (unsigned int)nbpl, + current_line, raster_line_buf); + current_line++; + } else + EMITL(bp, raster_line_buf); + +#ifdef DRAWGLYPH + printf("|\n"); +#endif + } + } else { + /* fprintf(stderr, "@\n"); */ + rowsleft = (long) ce->height ; + hbit = (long) ce->width ; + repeatcount = 0 ; + wordweight = 32 ; + word = 0 ; + rp = 1 ; + while ( rowsleft > 0 ) { + count = pk_packed_num() ; + bp = 0; + + while (count > 0) { + if ((count < wordweight) && (count < hbit)) { + if (turnon) + word += + gpower[wordweight] - + gpower[wordweight - count] ; + + hbit -= count ; + wordweight -= count ; + count = 0 ; + } else if ((count >= hbit) && (hbit <= + wordweight)) { + + if (turnon) + word += + gpower[wordweight] - + gpower[wordweight - hbit] ; + + row[rp] = word ; + + /*fprintf(stderr, " @ \n");*/ + for (i = 0; i <= (long) repeatcount; i++) { int ii; + +#ifdef DRAWGLYPH + printf("*** |"); +#endif + for (ii = 1; ii < wordwidth; ii++) { + tl = row[ii]; + + OUTCHAR((tl >> 24 & 0xFF)); + OUTCHAR((tl >> 16 & 0xFF)); + OUTCHAR((tl >> 8 & 0xFF)); + OUTCHAR((tl & 0xFF)); + +#ifdef DRAWGLYPH + { int k; + for (k=31; k>=0; k--) { + if ((power[k] & row[ii])!=0) printf("M"); + else printf("."); + } + } +#endif + } + tl = row[wordwidth]; + for (j = 3; j >= (wordwidth *4 - (long)nbpl); + j--) { + + OUTCHAR(((tl >> (j << 3)) & 0xff)); + +#ifdef DRAWGLYPH + { int k; + for (k=7; k>=0; k--) { + if ((power[k] & ((tl >> (j << 3)) & 0xff))!=0) printf("M"); + else printf("."); + } + } +#endif + } + + if (raster) { + RasterLine(ce, + (unsigned int)nbpl, + current_line, + raster_line_buf); + current_line++; + } else + EMITL(bp, raster_line_buf); + + bp = 0; + +#ifdef DRAWGLYPH + printf("| "); + for (j=1;j<=(long)wordwidth;j++) printf("%02lX/",row[j]); + printf(" raster=%d\n",raster); +#endif + } + + rowsleft -= (long)repeatcount + 1 ; + repeatcount = 0 ; + rp = 1 ; + word = 0 ; + wordweight = 32 ; + count -= hbit ; + hbit = (long)ce->width ; + } else { + if (turnon) word += gpower[wordweight] ; + row[rp] = word ; + rp = rp + 1 ; + word = 0 ; + count -= wordweight ; + hbit -= wordweight ; + wordweight = 32 ; + } + } /* .....while count > 0 */ + if (turnon) + turnon = FALSE; + else + turnon = TRUE; + } /* ...... rowsleft > 0 */ + if ((rowsleft != 0) || (hbit != (long)ce->width)) + Fatal("Bad pk file----more bits than required!\n"); + } /* .... create normally packed raster */ +} + + +unsigned char getnyb () +{ + register unsigned char temp ; + if ( bitweight == 0 ) { + inputbyte = PKBYTE ; + bitweight = 16 ; + } + temp = inputbyte / bitweight ; + inputbyte -= temp * bitweight ; + bitweight /= 16 ; + return ( temp ) ; +} + + +long +pk_packed_num () +{ /*@= */ + register int i; + long j; + + i = (int)getnyb(); + if (i == 0) { + do { + j = (long)getnyb(); + i++; + } while (j == 0) ; + while (i > 0) { + j = j * 16 + (long)getnyb() ; + i--; + }; + return (j - 15 + (13 - dyn_f) * 16 + dyn_f) ; + } else if (i <= (int)dyn_f) { + return ((long)i); + } else if (i < 14) { + return ((i-(long)dyn_f - 1) * 16 + (long)getnyb() + dyn_f + 1); + } else { + if (i == 14) { + repeatcount = (int) pk_packed_num() ; + } else { + repeatcount = 1 ; + } + /* fprintf(stderr,"repeatcount = [%d]\n",repeatcount); */ + return (pk_packed_num()) ; /* tail end recursion !! */ + } +} +#endif + +#ifndef USEPXL +void bad_gf(n) + int n; +{ + Fatal("Bad gf file, case %d\n",n); /* See gf.c */ +} +#endif +/*-->FormFeed*/ +/**********************************************************************/ +/***************************** FormFeed ******************************/ +/**********************************************************************/ +void +FormFeed() +{ + +#ifdef IBM3812 + unsigned short pages; + if ( (ndone == 0) && (FirstAlternate)){ + for (pages = 1; pages < ncopies; pages++) { + PMPout(2, "\321\300"); /* PMP-command xD1C0 */ + } + PMPout(2, "\321\100"); /* PMP-command xD140 */ + } else { + for (pages = 1; pages < ncopies; pages++){ + PMPout(2, "\321\200"); /* PMP-command xD180 */ + } + PMPout(2, "\321\0"); /* PMP-command xD100 */ + } +#endif +#ifdef LJ + EMITC('\f'); +#endif +} -- cgit v1.2.3