Back to index

tetex-bin  3.0
dvi2xx.c
Go to the documentation of this file.
00001 /* $Id: dvi2xx.c,v 2.5 1997/12/08 20:52:20 neumann Exp $ */
00002 #define VERSION "2.6p2 (dviljk)"
00003 /*
00004 #define DEBUGGS 1
00005 */
00006 /**********************************************************************
00007  ****************************  Intro  *********************************
00008  **********************************************************************
00009  * This program translates TeX's DVI-Code into device dependent
00010  * code of either the
00011  *
00012  *     -   HP-LASERJET+ and compatibles (PCL), or the
00013  *     -   IBM 3812 pageprinter
00014  *
00015  * depending on the preprocessor switches specified before compilation.
00016  * The program is written to run on a PC XT/AT/PS2 under MS-DOS. It can
00017  * be compiled nicely with MSC Rel. 3.0-5.1 with option -AL (large memory
00018  * model).  Take care that in the CONFIG.SYS file the FILES parameter
00019  * is set to 20; otherwise reduce MAXOPEN.  640K are recommended.
00020  * I use link option /stack:9000 to increase runtime stack.
00021  * It also works without modifications under Unix System V.
00022  **********************************************************************
00023  *            Adapted for the PC:    Gustaf Neumann
00024  *            +1002 stuff        University of Economics
00025  *            +3812 support      Augasse 2-6
00026  *            +Output buffering      A-1090 Vienna, AUSTRIA
00027  *            +lpt binary support    Tel. *43-222-340525/533
00028  *            +pk-89 stuff                   773
00029  *            +pixelpaths
00030  *            +alternative directory structure
00031  *            +code compiles also under Unix V (HP/UX)
00032  *                      (thx Michael Haberler)
00033  *            +huge characters (a character bigger than 32K)
00034  *                      formats PXL1001 and PXL 1002
00035  *                     (use: raster graphics)
00036  *            +reduction of the produced code
00037  *            +new options -X -Y -c -g
00038  *            +changed options -r (LJ now default from first to last)
00039  *                     -x,-y  (accept floats)
00040  *            +new option -z for LJ: print testpage containing
00041  *                     pagecounter after printjob
00042  *            +try to overcome font limit on LJ (max 16 fonts/page) and
00043  *             (max 32 fonts/document):
00044  *                     additional fonts are drawn as bitmap-
00045  *                     graphics.
00046  *            +allows to set character close to the paperedge on LJ
00047  *            +gf-supprt (by Joe Kelsey joe@Pacer.com)
00048  *                gf.c and gf.h from mitdevices/dvi2ps
00049  *            +clipping of rules
00050  *            +OS/2 defines from Rutger Berns, apprmb@hheouh50.bitnet
00051  *
00052  *            BITNET/EARN:       NEUMANN at AWIWUW11
00053  **********************************************************************
00054  * fixes in LJ-mode:  rule-drawing,
00055  *            characters with 127<=height<=200
00056  *            reset printer at beginning and end of each job
00057  *            better positioning of rules
00058  * 30.1.89 (0.48) bug fixed for files containing >32 fonts (thanks A. Brosig),
00059  *                different font assignment heuristic
00060  * fixes in 3812-mode:  14.juli 87  positioning of rastered characters
00061  *            better positioning of rules
00062  * general fixes
00063  * 1.1.88         page origin set to 1in/1in (hopefully everywhere)
00064  * 22.7.88        reset y-position for each page-eject
00065  * 15.1.89        fixing bug is space allocation for EmitFileName
00066  *                (thanks to Bernhard Simon)
00067  * 15.3.91 (0.49) landscape support for lj ii p, lj iii and lj 2000
00068  *                fixing rule drawing problems for IBM3812 in landcape mode,
00069  *                256 character clean (lj family and IBM3812)
00070  * 5.5.91 (0.50)  -DSEVENBIT added for older LJ-emulations
00071  *                -D1, -D2, -D-, -D1-, -D2- options added due to suggestions
00072  *                from Tomasz Wolniewicz
00073  **********************************************************************
00074  * Preprocessor switches:
00075  *      #define DEBUG    for massive printing of trace information
00076  *               when -d cmdline option specified
00077  *      #define IBM3812  produce output for the IBM3812 pageprinter
00078  *      #define LJ       produce output for the HP Laserjet+ or LJ II
00079  *      #define LJ2P     produce output for the HP Laserjet LJ IIP, LJ III
00080  *                       or LaserJet 2000
00081  *      #define LJ_LARGE_FONT_MEMORY  large FONT Memory for LJ printer family
00082  *      #define DRAWGLYPH draws PK-Glyphs on stderr
00083  *      #define USEPXL   use PXL and PK fonts rather than gf fonts
00084  **********************************************************************
00085  *             Adapted for Acorn RISC OS computers: Andreas Dehmel
00086  *             Address:    Andreas Dehmel
00087  *                       Am Schorn 18
00088  *                       82327 Tutzing
00089  *                       Germany
00090  *                       dehmel@informatik.tu-muenchen.de
00091  *
00092  *             Changes:
00093  *           - Split the whole thing up into smaller files
00094  *           - Rearranged certain parts of the output
00095  *           - If fonts are missing a taskobey file is created that
00096  *             contains MF commands to build the fonts.
00097  *           - SUPPORT FOR DIAGRAMS AS USED IN DVIVIEW!!!
00098  *           - Fixed problem of raster chars being scrambled when diagram
00099  *             printouts were on the same page.
00100  *             - Raster chars and fonts can now also be downloaded in
00101  *             compressed format; many thanks to Karl Berry!
00102  */
00103 
00104 #include "dvi2xx.h"
00105 
00106 #ifdef SEVENBIT
00107 #define VIS   33
00108 #define VIS2  (VIS+32)
00109 unsigned char
00110 VisChar(c)
00111 unsigned char   c;
00112 {
00113   c &= 0xff;
00114   if (c < VIS)
00115     return ((unsigned char)(160 + c));
00116   if (c < 128)
00117     return (c);
00118   if (c < (255 - VIS2))
00119     return ((unsigned char)(VIS2 + c));
00120   return (255);
00121 }
00122 #endif
00123 
00124 
00125 /**********************************************************************/
00126 /*******************************  main  *******************************/
00127 /**********************************************************************/
00128 int
00129 #if NeedFunctionPrototypes
00130 main(int argc, char *argv[])
00131 #else
00132 main(argc, argv)
00133 int     argc;
00134 char    *argv[];
00135 #endif
00136 {
00137   struct stack_entry {  /* stack entry */
00138     long4    h, v, w, x, y, z;  /* what's on stack */
00139   };
00140   short   command;           /* current command                         */
00141   long4   count[10];         /* the 10 counters at begining of each page*/
00142   long4   cpagep = 0;        /* current page pointer                    */
00143   bool    Emitting = _FALSE; /* outputting typsetting instructions?     */
00144   int     i;                 /* command parameter; loop index           */
00145   int     k;                 /* temporary parameter                     */
00146   char    n[STRSIZE];        /* command parameter                       */
00147   int     PassNo = 0;        /* which pass over the DVI page are we on? */
00148   bool    SkipMode = _FALSE; /* in skip mode flag                       */
00149   int     sp = 0;            /* stack pointer                           */
00150   struct  stack_entry stack[STACK_SIZE];  /* stack                      */
00151   char    SpecialStr[STRSIZE]; /* "\special" strings                    */
00152   long4   val, val2;         /* temporarys to hold command information  */
00153   long4   w = 0;             /* current horizontal spacing              */
00154   long4   x = 0;             /* current horizontal spacing              */
00155   long4   y = 0;             /* current vertical spacing                */
00156   long4   z = 0;             /* current vertical spacing                */
00157 
00158 #ifdef vms
00159   extern noshare int errno;
00160   extern noshare char *sys_errlist[];
00161 #else
00162 # if !defined (__riscos) && !defined (KPATHSEA)
00163   extern  char *sys_errlist[];
00164   extern  int   errno;
00165 # endif
00166 #endif
00167 
00168   /* Initialize pixel_files */   
00169   for (i = 0; i <= MAXOPEN; i++)
00170     pixel_files[i].pixel_file_id = FPNULL;
00171 
00172   x_origin = XDEFAULTOFF; /* x-origin in dots                    */
00173   y_origin = YDEFAULTOFF; /* y-origin in dots                    */
00174 
00175   setbuf(ERR_STREAM, NULL);
00176   (void) strcpy(G_progname, argv[0]);
00177 #ifdef KPATHSEA
00178   kpse_set_progname(argv[0]);
00179   kpse_set_program_enabled (kpse_pk_format, MAKE_TEX_PK_BY_DEFAULT, kpse_src_compile);
00180 #endif
00181   DecodeArgs(argc, argv);
00182 
00183 #ifdef LJ4
00184   if (CompressCharWidth < 0) {
00185     switch(UseCompression) {
00186     case 0: CompressCharWidth = COMPRESS_WIDTH0; break;
00187     case 2: CompressCharWidth = COMPRESS_WIDTH2; break;
00188     case 3: CompressCharWidth = COMPRESS_WIDTH3; break;
00189     }
00190   }
00191 #endif
00192 
00193 #ifdef KPATHSEA
00194   kpse_init_prog("DVILJ", RESOLUTION, MFMODE, "cmr10");
00195 #endif
00196 
00197   power[0] = 1;
00198   for (i = 1; i <= 31; i ++)
00199     power[i] = power[i - 1] << 1;
00200   gpower[0] = 0l;
00201   for ( i = 1; i <= 32; i ++)
00202     gpower[i] = gpower[i - 1] + power[i - 1];
00203 
00204   if ((i = (int)NoSignExtend(dvifp, 1)) != PRE) {
00205     Fatal("%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n",
00206           G_progname);
00207   }
00208   i = (int)SignExtend(dvifp, 1);
00209   if (i != DVIFORMAT) {
00210     Fatal( "%s: DVI format = %d, can only process DVI format %d files\n\n",
00211            G_progname, i, DVIFORMAT);
00212   }
00213 
00214   if (*EmitFileName == '-') {
00215 #ifdef RISC_USE_OSL
00216     EMTO = BOUTOPEN("Vdu:");
00217 #else
00218     EMTO = stdout;
00219 #endif
00220   }
00221   else
00222     if ((EMTO = BOUTOPEN(EmitFileName)) == FPNULL)
00223 #ifndef KPATHSEA
00224       Fatal("opening output file: fopen(%s) : %s", EmitFileName,
00225 #ifdef __riscos
00226             "Cannot open"
00227 #else
00228             sys_errlist[errno]
00229 #endif
00230             )
00231 #endif /* not KPATHSEA */
00232             ;
00233 #ifdef __riscos
00234   xosfile_set_type(EmitFileName,0xff4);
00235 #endif
00236 
00237   /* If EmitFileName is "-", we use stdout.  But it is by default open
00238      in TEXT mode, and we need to switch it to binary, unless they are
00239      writing to the screen (in which case they get what they deserve).  */
00240   if (O_BINARY && !isatty(fileno(outfp)))
00241     AssureBinary(fileno(outfp));
00242 
00243 #ifdef TIMING
00244 #ifdef BSD_TIME_CALLS
00245   ftime(&timebuffer);
00246   start_time = timebuffer.time + (float)(timebuffer.millitm) / 1000.0;
00247 #else
00248   gettimeofday(&Tp, NULL);
00249   start_time = Tp.tv_sec + ((float)(Tp.tv_usec))/ 1000000.0;
00250 #endif
00251 #endif
00252 
00253   /* it is important that these be the very first things output !!! */
00254   if ( G_header )
00255     CopyFile( HeaderFileName );
00256 
00257   /*****************************/
00258   /*for( i0=0; i0<nif; i0++ )  */    /* copy all included files */
00259   /*    CopyFile( Ifile[i0] ); */
00260   /*****************************/
00261 
00262 #ifdef IBM3812
00263   PMPout(3, "\307\310\366");          /* unload all fonts and macros */
00264   EMITWORD(MAX_PAGE_WIDTH);
00265   EMITWORD(MAX_PAGE_HEIGHT);
00266   if (Landscape)
00267     PMPout(2, "\322\1");
00268 #endif
00269 
00270 #ifdef LJ
00271   if (ResetPrinter)
00272     EMIT1("\033E");
00273 # ifdef LJ4
00274   EMIT2("\033%%-12345X@PJL SET RESOLUTION=%d\012",RESOLUTION);
00275   EMIT1("@PJL SET PAGEPROTECT=OFF\012");
00276   EMIT1("@PJL ENTER LANGUAGE=PCL\012");
00277   if (econoMode && LJ6)
00278       EMIT1("@PJL SET ECONOMODE=ON\012");  
00279   EMIT3("\033&u%dD\033*t%dR",RESOLUTION,RESOLUTION);
00280   if (econoMode && !LJ6)
00281     EMIT1("\033*v1T");
00282 # endif
00283 # ifdef LJ2P
00284   if (DuplexMode)
00285     EMIT2("\033&l%dS", DuplexMode);
00286 # endif
00287   if (Landscape)
00288     EMIT1("\033&l1O\033*rF");
00289   if (pagesize>0) {
00290 # ifndef vms
00291     EMIT2("\033&l%hdaE\033&aL", pagesize);
00292 # else
00293     EMIT2("\033&l%daE\033&aL", pagesize);
00294 # endif
00295   } else
00296     EMIT1("\033&lE\033&aL");
00297 
00298   if (ncopies>1) {
00299 # ifndef vms
00300     EMIT2("\033&l%hdX", ncopies);
00301 # else
00302     EMIT2("\033&l%dX", ncopies);
00303 # endif
00304   }
00305 #endif /* LJ */
00306 
00307   if (DoublePage) {
00308     StartPrintPages = PrintPages;
00309 #ifdef IBM3812
00310     Reverse = (bool)!Reverse; /* perverse and strange */
00311 #endif
00312   }
00313 
00314   if (ManualFeed)
00315       EMIT(outfp, "\033&l2H"); /* Manual Feed */
00316 
00317   if (Reverse) {
00318 #ifdef DEBUG
00319     if (Debug)
00320       fprintf(ERR_STREAM, "reverse\n");
00321 #endif
00322     ReadPostAmble(_TRUE);
00323     FSEEK(dvifp, ppagep, SEEK_SET);
00324   } else {
00325     ReadPostAmble(_TRUE);
00326     FSEEK(dvifp,  14l, SEEK_SET);
00327     k = (int)NoSignExtend(dvifp, 1);
00328     GetBytes(dvifp, n, k);
00329   }
00330   PassNo = 0;
00331 
00332   while (_TRUE)  {
00333     command = (short) NoSignExtend(dvifp, 1);
00334 #ifdef DEBUG
00335     if (Debug)
00336       fprintf(ERR_STREAM,"CMD@%ld:\t%d\n", (long) ftell(dvifp) - 1, command);
00337 #endif
00338     switch (command)  {
00339     case SET1:
00340     case SET2:
00341     case SET3:
00342     case SET4:
00343       val = NoSignExtend(dvifp, (int)command - SET1 + 1);
00344       if (!SkipMode)
00345         SetChar(val, command, PassNo, _TRUE,_FALSE);
00346       break;
00347     case SET_RULE:
00348       val = NoSignExtend(dvifp, 4);
00349       val2 = NoSignExtend(dvifp, 4);
00350       if (Emitting)
00351         SetRule(val, val2, 1);
00352       break;
00353     case PUT1:
00354     case PUT2:
00355     case PUT3:
00356     case PUT4:
00357       val = NoSignExtend(dvifp, (int)command - PUT1 + 1);
00358       if (!SkipMode)
00359         SetChar(val, command, PassNo, _TRUE,_FALSE);
00360       break;
00361     case PUT_RULE:
00362       val = NoSignExtend(dvifp, 4);
00363       val2 = NoSignExtend(dvifp, 4);
00364       if (Emitting)
00365         SetRule(val, val2, 0);
00366       break;
00367     case NOP:
00368       break;
00369     case BOP:
00370       cpagep = FTELL(dvifp) - 1;
00371       DEBUG_PRINT ("BOP for [");
00372       for (i = 0; i <= 9; i++) {
00373         count[i] = NoSignExtend(dvifp, 4);
00374         DEBUG_PRINT1 ("%d.", (int) count[i]);
00375       }
00376       DEBUG_PRINT1 ("] at %ld.\n", cpagep);
00377       ppagep = (long)NoSignExtend(dvifp, 4);
00378       h = v = w = x = y = z = 0;
00379       hh = vv = 0;
00380       last_rx = last_ry = UNKNOWN;
00381       sp = 0;
00382       fontptr = NULL;
00383       prevfont = NULL;
00384       DoBop();
00385       /*
00386         fprintf(ERR_STREAM,"skimode %d, count %d, F %d, L %d\n",
00387         (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified);
00388         */
00389       SkipMode = (bool)((FirstPageSpecified && count[0] < FirstPage) ||
00390                         (LastPageSpecified && count[0] > LastPage ));
00391       /*
00392         fprintf(ERR_STREAM,"skimode %d, count %d, F %d, L %d\n",
00393         (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified);
00394         */
00395 
00396       if (DoublePage && !SkipMode) {
00397         if (PassNo == 0) {
00398           LastPtobePrinted = count[0];
00399           if (!Reverse && (WouldPrint == 0)) {
00400             if (count[0] == 0l) {
00401               ZeroPage = _TRUE;
00402               EvenPage = _FALSE;
00403             }
00404             else {
00405               EvenPage = (bool)( (count[0]<0? labs(count[0])+1: count[0]) %2 == 0);
00406 
00407               if (PrintEmptyPages && EvenPage && PageParity==1) {
00408                 WouldPrint ++;
00409                 if (PrintFirstPart) {
00410                   qfprintf(ERR_STREAM,"[EvenPage] ");
00411                   FormFeed();
00412                 }
00413               }
00414             }
00415           }
00416           WouldPrint ++;
00417           /*
00418             fprintf(ERR_STREAM, "doublepage %d, page parity = %d, 1=%d 2=%d, Reverse %d, WouldPrint %d, fpZ %d\n",
00419             (int)DoublePage, (int)PageParity,(int)PrintFirstPart,(int)PrintSecondPart,
00420             (int)Reverse, (int)WouldPrint, (int)ZeroPage);
00421             */
00422         }
00423         if (!PrintFirstPart && PageParity==1) {
00424           if (count[0] == 0) {
00425             ZeroPage = _TRUE;
00426             EvenPage = _FALSE;
00427           }
00428           SkipMode = _TRUE;
00429         }
00430         else {
00431           /*
00432             fprintf(ERR_STREAM,"FirstPart\n count %d, mod %d, pp %d\n",(int)count[0],(int)count[0]%2,PageParity);
00433             */
00434           SkipMode = 
00435             (bool)(PageParity != (short)((count[0]<0 ? 
00436                                           labs(count[0])+1 : count[0])%2));
00437           if (count[0] == 0) SkipMode = (bool)!SkipMode;
00438         }
00439 
00440       }
00441       Emitting = (bool)((PassNo != 0) && !SkipMode);
00442       /*
00443         fprintf(ERR_STREAM,"Emitting= %d, PassNo=%d, SkipMode = %d\n",(int)Emitting,(int)PassNo,(int)SkipMode);
00444         */
00445       if ( !SkipMode ) {
00446         if (PassNo == 0)
00447           qfprintf(ERR_STREAM,"[%ld",  (long)count[0]);
00448       }
00449       break;
00450     case EOP:
00451       if ( !SkipMode ) {
00452         if (PassNo == 0) {
00453           /* start second pass on current page */
00454           FSEEK(dvifp, cpagep, SEEK_SET);
00455           PassNo = 1;
00456 #ifdef DEBUG
00457           if (Debug)
00458             fprintf(ERR_STREAM,"\nStarting second pass\n");
00459 #endif
00460 
00461         } else {
00462           /* end of second pass, and of page processing */
00463 
00464           last_rx = last_ry = UNKNOWN;
00465           FormFeed();
00466           ++ndone;
00467 
00468           qfprintf(ERR_STREAM,"] ");
00469           if ( (ndone % 10) == 0 )
00470             qfprintf(ERR_STREAM,"\n");
00471 
00472           if (DoublePage) --PrintPages;
00473           if (--PrintPages < 1) AllDone(_TRUE);
00474           PassNo = 0;
00475         }
00476       } else
00477         PassNo = 0;
00478 
00479       if ( PassNo == 0 && Reverse ) {
00480         if ( ppagep > 0 )
00481           FSEEK(dvifp, ppagep, SEEK_SET);
00482         else {
00483           if (DoublePage && !SkipMode)
00484             ZeroPage = (bool)(count[0] == 0);
00485 
00486           if (ZeroPage)
00487             EvenPage = _FALSE;
00488           else
00489             EvenPage = (bool)((int)LastPtobePrinted%2 == 0);
00490 
00491           AllDone(_FALSE);
00492         }
00493       }
00494       break;
00495     case PUSH:
00496       if (sp >= STACK_SIZE)
00497         Fatal("stack overflow");
00498       stack[sp].h = h;
00499       stack[sp].v = v;
00500       stack[sp].w = w;
00501       stack[sp].x = x;
00502       stack[sp].y = y;
00503       stack[sp].z = z;
00504       sp++;
00505       break;
00506     case POP:
00507       --sp;
00508       if (sp < 0)
00509         Fatal("stack underflow");
00510       h = stack[sp].h;
00511       v = stack[sp].v;
00512       w = stack[sp].w;
00513       x = stack[sp].x;
00514       y = stack[sp].y;
00515       z = stack[sp].z;
00516       last_rx = last_ry = UNKNOWN;
00517       break;
00518     case RIGHT1:
00519     case RIGHT2:
00520     case RIGHT3:
00521     case RIGHT4:
00522       val = SignExtend(dvifp, (int)command - RIGHT1 + 1);
00523       if (Emitting)
00524         MoveOver(val);
00525       break;
00526     case W0:
00527       if (Emitting)
00528         MoveOver(w);
00529       break;
00530     case W1:
00531     case W2:
00532     case W3:
00533     case W4:
00534       w = SignExtend(dvifp, (int)command - W1 + 1);
00535       if (Emitting)
00536         MoveOver(w);
00537       break;
00538     case X0:
00539       if (Emitting)
00540         MoveOver(x);
00541       break;
00542     case X1:
00543     case X2:
00544     case X3:
00545     case X4:
00546       x = SignExtend(dvifp, (int)command - X1 + 1);
00547       if (Emitting)
00548         MoveOver(x);
00549       break;
00550     case DOWN1:
00551     case DOWN2:
00552     case DOWN3:
00553     case DOWN4:
00554       val = SignExtend(dvifp, (int)command - DOWN1 + 1);
00555       if (Emitting)
00556         MoveDown(val);
00557       break;
00558     case Y0:
00559       if (Emitting)
00560         MoveDown(y);
00561       break;
00562     case Y1:
00563     case Y2:
00564     case Y3:
00565     case Y4:
00566       y = SignExtend(dvifp, (int)command - Y1 + 1);
00567       if (Emitting)
00568         MoveDown(y);
00569       break;
00570     case Z0:
00571       if (Emitting)
00572         MoveDown(z);
00573       break;
00574     case Z1:
00575     case Z2:
00576     case Z3:
00577     case Z4:
00578       z = SignExtend(dvifp, (int)command - Z1 + 1);
00579       if (Emitting)
00580         MoveDown(z);
00581       break;
00582     case FNT1:
00583     case FNT2:
00584     case FNT3:
00585     case FNT4:
00586       k = NoSignExtend(dvifp, (int) command - FNT1 + 1);
00587       if (!SkipMode) {
00588         SetFntNum(k, Emitting);
00589       }
00590       break;
00591     case XXX1:
00592     case XXX2:
00593     case XXX3:
00594     case XXX4:
00595       k = (int)NoSignExtend(dvifp, (int)command - XXX1 + 1);
00596       GetBytes(dvifp, SpecialStr, k);
00597       if (Emitting)
00598         DoSpecial(SpecialStr, k);
00599       break;
00600     case FNT_DEF1:
00601     case FNT_DEF2:
00602     case FNT_DEF3:
00603     case FNT_DEF4:
00604       k = (int)NoSignExtend(dvifp, (int)command - FNT_DEF1 + 1);
00605       SkipFontDef();    /* SkipFontDef(k); */
00606       break;
00607     case PRE:
00608       Fatal("PRE occurs within file");
00609       break;
00610     case POST:
00611       AllDone(_FALSE);
00612       PassNo = 0;
00613       break;
00614     case POST_POST:
00615       Fatal("POST_POST with no preceding POST");
00616       break;
00617     default:
00618       if (command >= FONT_00 && command <= FONT_63) {
00619         if (!SkipMode)
00620           SetFntNum((long4)command - FONT_00, Emitting);
00621       } else if (command >= SETC_000 && command <= SETC_127) {
00622         if (!SkipMode) {
00623           SetString(command, PassNo);
00624         }
00625       } else
00626         Fatal("%d is an undefined command", command);
00627       break;
00628     }
00629   } /* while _TRUE */
00630 }
00631 
00632 
00633 
00634 
00635 
00636 
00637 /*------------------------ begin dviIO.c ----------------------------------*/
00638 
00639 /* The following functions buffer input/output during CopyFile / CopyHPFile
00640    Write functions are only needed if RISC_BUFFER is defined; otherwise output
00641    is not buffered. */
00642 
00643 /* read a buffered byte */
00644 char 
00645 #if NeedFunctionPrototypes
00646 b_read(FILEPTR spfp)
00647 #else
00648 b_read(spfp)
00649 FILEPTR spfp;
00650 #endif
00651 {
00652   if (biact >= binumber) {
00653 #ifdef RISC_USE_OSL
00654     binumber = BUFFSIZE - read_multi(buffin,1,BUFFSIZE,spfp);
00655 #else
00656     binumber = read_multi(buffin,1,BUFFSIZE,spfp);
00657 #endif
00658     biact = 0;
00659   }
00660   return binumber == 0 ? 0 : buffin[biact++];
00661 }
00662 
00663 #ifdef RISC_BUFFER
00664 void 
00665 #if NeedFunctionPrototypes
00666 b_write(FILEPTR spfp, char c) /* write a buffered byte */
00667 #else
00668 b_write(spfp, c)
00669 FILEPTR spfp;
00670 char c;
00671 #endif
00672 {
00673   if (boact >= BUFFSIZE) {
00674     write_multi(buffout,1,BUFFSIZE,spfp);
00675     boact = 0;
00676   }
00677   buffout[boact++] = c;
00678 }
00679 
00680 void 
00681 #if NeedFunctionPrototypes
00682 b_wrtmult(FILEPTR spfp, char *buf, int len) /* write a sequence of bytes to the output buffer */
00683 #else
00684 b_wrtmult(spfp, buf, len)
00685 FILEPTR spfp;
00686 char *buf;
00687 int len;
00688 #endif
00689 {
00690   register int i;
00691 
00692   if ((len > (BUFFSIZE - boact)) || (len >= (BUFFSIZE/4))) {
00693     write_multi(buffout,1,boact,spfp);
00694     /* Copy only small blocks; large ones are written directly */
00695     if (len < (BUFFSIZE/4)) {
00696       for (i = 0; i<len; i++) 
00697         buffout[i] = buf[i];
00698       boact = len;
00699     } else {
00700       write_multi(buf,1,len,spfp); 
00701       boact = 0;
00702     }
00703   }
00704   else {
00705     for (i = 0; i<len; i++) 
00706       buffout[boact++] = buf[i];
00707   }
00708 }
00709 
00710 /* flush the output buffer */
00711 void 
00712 #if NeedFunctionPrototypes
00713 b_oflush(FILEPTR spfp)
00714 #else
00715 b_oflush(spfp)
00716 FILEPTR spfp;
00717 #endif
00718 {
00719   write_multi(buffout,1,boact,spfp);
00720   boact = 0;
00721 }
00722 #endif
00723 /* end of buffer handling functions */
00724 
00725 
00726 /*-->CopyFile*/   /* copy a file straight through to output */
00727 /*********************************************************************/
00728 /***************************** CopyFile ******************************/
00729 /*********************************************************************/
00730 void
00731 #if NeedFunctionPrototypes
00732 CopyFile(char *str )
00733 #else
00734 CopyFile( str )
00735 char    *str;
00736 #endif
00737 {
00738   FILEPTR spfp;
00739   int     todo;
00740 
00741   if ( (spfp = BINOPEN(str)) == FPNULL ) {
00742     Warning("Unable to open file %s", str );
00743     return;
00744   }
00745   qfprintf(ERR_STREAM," [%s", str);
00746 #ifdef RISC_BUFFER
00747   b_oflush(outfp);
00748 #endif
00749   do {
00750     todo = read_multi(buffin,1,BUFFSIZE,spfp);
00751     write_multi(buffin,1,todo,outfp);
00752   }
00753   while (todo == BUFFSIZE);
00754 
00755   BCLOSE(spfp);
00756   qfprintf(ERR_STREAM,"]");
00757 }
00758 
00759 
00760 /*-->CopyHPFile*/  /* copy a HP file to output removing unwanted control codes*/
00761 /*********************************************************************/
00762 /***************************** CopyHPFile ******************************/
00763 /*********************************************************************/
00764 #if NeedFunctionPrototypes
00765 int getnum(FILEPTR spfp, char *t, char *numstr) 
00766 #else
00767 int getnum(spfp, t, numstr) 
00768 FILEPTR spfp;
00769 char *t, *numstr;
00770 #endif
00771 {
00772   int count=0;
00773   for (*t = (char)b_read(spfp); *t<0x40; *t = (char)b_read(spfp))
00774     numstr[count++] = *t;
00775   numstr[count] = 0;
00776   return atoi(numstr);
00777 }
00778 
00779 #if NeedFunctionPrototypes
00780 void setOffset(char dir, char sign, int pos) 
00781 #else
00782 void setOffset(dir, sign, pos, first) 
00783 char dir, sign;
00784 int pos;
00785 #endif
00786 {
00787   if ((sign == '+' || sign == '-') && pos > 0 ) {
00788     EMIT4("\033*p%c%d%c",sign,pos,dir);
00789 #ifdef DEBUGGS   
00790     fprintf(stderr, "relative: *p%c%d%c\n", sign, pos, dir);
00791 #endif
00792   } else if (pos>0) {
00793     EMIT3("\033*p%d%c",pos,dir);
00794 #ifdef DEBUGGS   
00795     fprintf(stderr, "absolute: *p%d%c\n", pos, dir);
00796 #endif
00797     if (dir == 'X') 
00798       last_rx = pos;
00799     else 
00800       last_ry = pos;
00801   } else {
00802     /*EMIT3("\033*p%d%c",pos,dir);*/
00803 #ifdef DEBUGGS   
00804     fprintf(stderr, "Relative: *p%d%c\n", pos, dir);
00805 #endif
00806   }
00807 }
00808 
00809 
00810 void
00811 #if NeedFunctionPrototypes
00812 CopyHPFile(char *str )
00813 #else
00814 CopyHPFile( str )
00815 char    *str;
00816 #endif
00817 {
00818   FILEPTR spfp;
00819   char    t,numstr[20];
00820   int     count,miny,minx,num;
00821 
00822   if ( (spfp = BINOPEN(str)) == FPNULL ) {
00823     Warning("Unable to open file %s", str);
00824     return;
00825   }
00826   minx = 32767;                 /* Set to a high value initially */
00827   miny = 32767;
00828 
00829   /* Pass through the input PCL file twice.  The first time find the
00830      smallest x- and y-offsets so that they can be subtracted out when
00831      sending positioning commands later.  The second pass strips the
00832      unwanted commands from the input file and outputs the rest */
00833 
00834   /* reset the input buffer */
00835   binumber = 0; 
00836   biact = 0;
00837 
00838   qfprintf(ERR_STREAM," [%s", str);
00839   /* Test for !EOF now ((binumber == BUFFSIZE) || (biact < binumber)) */
00840   do {
00841     t = (char)b_read(spfp);
00842     if (t==0x1B) { /* Find the escape character */
00843       t = (char)b_read(spfp);
00844       if (t==0x2A) { /* This indiactes the start of a graphics command */
00845         t = (char)b_read(spfp);
00846         switch(t) {
00847         case('p'):
00848           /* These are the graphics positioning commands */
00849           /* Find the smallest x and y offsets */
00850           num = getnum(spfp, &t, numstr);
00851 
00852           /* Take into account the possible different ordering */
00853           /* of the commands (x first, y first) */
00854 
00855           if (t=='Y' || t=='y') {
00856             if (numstr[0]!='+' && numstr[0]!='-' && num<miny) 
00857               miny = num;
00858             if (t=='y') {
00859               num = getnum(spfp, &t, numstr);
00860               if (numstr[0]!='+' && numstr[0]!='-' && num<minx) 
00861                 minx = num;
00862             }
00863           }
00864           if (t=='X' || t=='x') {
00865             if (numstr[0]!='+' && numstr[0]!='-' && num<minx) 
00866               minx = num;
00867 
00868             if (t=='x') {
00869               num = getnum(spfp, &t,numstr);
00870               if (numstr[0]!='+' && numstr[0]!='-' && num<miny)
00871                 miny = num;
00872             }
00873           }
00874           break;
00875           /* Ignore all other commands for the moment - just read them */
00876         case(0x74):
00877           for (t = (char)b_read(spfp); t != 0x52; t = (char)b_read(spfp));
00878           break;
00879 
00880         case(0x72):
00881           for (t = (char)b_read(spfp); ((t< 0x40)||(t>0x60)); t = (char)b_read(spfp));
00882           break;
00883 
00884         case(0x62):
00885           num = 0;
00886           count = 0;
00887           /* Read in the correct number of bytes of raster graphics */
00888           /* so that we don't get commands and raster graphics confused */
00889 
00890           for (t = (char)b_read(spfp); ((t<0x40)||(t>=0x60)); t = (char)b_read(spfp))
00891             numstr[count++]=t;
00892           numstr[count]=0;
00893           if (t==0x4D)
00894             for(t = numstr[count = 0]; t!=0; t = numstr[++count]);
00895           if (t==0x57) {
00896             for(t = numstr[count = 0]; t!=0; t = numstr[++count]);
00897             for(count = atoi(numstr); count>0; count--)
00898               t = (char)b_read(spfp);
00899           }
00900           break;
00901 
00902         case(0x63):
00903           for (t = (char)b_read(spfp); t< 0x40 || t>0x60; t = (char)b_read(spfp));
00904           break;
00905 
00906         default:
00907           break;
00908         }
00909       }
00910     }
00911   }
00912   while ((binumber == BUFFSIZE) || (biact < binumber));
00913 
00914   BCLOSE(spfp);
00915   qfprintf(ERR_STREAM,"]");
00916 
00917   if ( (spfp = BINOPEN(str)) == FPNULL ) {
00918     Warning("Unable to open file %s", str );
00919     return;
00920   }
00921   qfprintf(ERR_STREAM," [%s", str);
00922   /* reset input buffer again */
00923   binumber = 0; 
00924   biact = 0;
00925 
00926 
00927   /* Pass through the input file again but this time output the */
00928   /* retained PCL commands */
00929 #ifdef DEBUGGS   
00930   fprintf(stderr,"\nminx=%d, miny=%d, xg=%d, yg=%d\n", 
00931           minx, miny, x_goffset, y_goffset);
00932 #endif  
00933   do {
00934     t = (char)b_read(spfp);
00935     if (t==0x1B) {
00936       t = (char)b_read(spfp);
00937       if (t==0x2A) {
00938         t = (char)b_read(spfp);
00939         switch(t) {
00940         case('p'):
00941           num = getnum(spfp, &t,numstr);
00942           if (t == 'Y' || t == 'y') {
00943             if (numstr[0]!='+' && numstr[0]!='-') {
00944               /* Subtract the minimum offset found in first pass */
00945               /* and add in the current vertical offset */
00946               setOffset('Y',numstr[0],
00947                         num-miny + (int)PIXROUND(v,vconv) + y_goffset);
00948             } else {
00949               setOffset('Y',numstr[0], num);
00950             }
00951             
00952             if (t == 'y') {
00953               num = getnum(spfp, &t,numstr);
00954               if (numstr[0]!='+' && numstr[0]!='-') {
00955                 /*Add in correct horizontal offset */
00956                 setOffset('X',numstr[0],
00957                           num - minx + (int)PIXROUND(h,hconv) + x_goffset);
00958               } else if (num>=0) {
00959                 setOffset('X',numstr[0], num);
00960               }
00961             }
00962           }
00963             
00964           if (t=='X' || t=='x') {
00965             if (numstr[0]!='+' && numstr[0]!='-') {
00966               /*Add in the correct horizontal offset*/
00967               setOffset('X',numstr[0],
00968                         num - minx + (int)PIXROUND(h,hconv) + x_goffset);
00969             } else { 
00970               setOffset('X',numstr[0], num);
00971             }
00972             
00973             if (t=='x') {
00974               num = getnum(spfp, &t,numstr);
00975               if (numstr[0]!='+' && numstr[0]!='-') {
00976                 /* Subtract the minimum offset found in first pass */
00977                 /* and add in the current vertical offset */
00978                 setOffset('Y',numstr[0],
00979                           num-miny + (int)PIXROUND(v,vconv) + y_goffset);
00980               } else {
00981                 setOffset('Y',numstr[0], num);
00982               }
00983             }
00984           }
00985           break;
00986 
00987         case(0x74):
00988           /* Set the Raster resolution */
00989           EMIT1("\033*t");
00990           for (t = (char)b_read(spfp); t != 0x52; t = (char)b_read(spfp))
00991             EMITC(t);
00992           EMITC(t);
00993           break;
00994 
00995         case(0x72):
00996           /* Raster Graphics commands such as start */
00997           EMIT1("\033*r");
00998           for (t = (char)b_read(spfp); t< 0x40 || t>0x60; t = (char)b_read(spfp))
00999             EMITC(t);
01000           EMITC(t);
01001           break;
01002 
01003         case(0x62):
01004           /* Transfer the correct number of bytes of raster graphics */
01005           EMIT1("\033*b");
01006           num = 0;
01007           count = 0;
01008           for (t = (char)b_read(spfp); t<0x40 || t>=0x60; t = (char)b_read(spfp))
01009             numstr[count++] = t;
01010           numstr[count] = 0;
01011           if (t==0x4D) {
01012             for (t = numstr[count = 0]; t!=0; t = numstr[++count])
01013               EMITC(t);
01014             EMIT1("M");
01015           }
01016           if (t==0x57) {
01017             for(t = numstr[count = 0]; t!=0; t = numstr[++count])
01018               EMITC(t);
01019             EMIT1("W");
01020             for (count = atoi(numstr); count>0; count--) {
01021               t = (char)b_read(spfp);
01022               EMITC(t);
01023             }
01024           }
01025           break;
01026 
01027         case(0x63):
01028           /* Rectangular draw commands */
01029           EMIT1("\033*c");
01030           for (t = (char)b_read(spfp); t<0x40 || t>0x60; 
01031                t = (char)b_read(spfp))
01032             EMITC(t);
01033           EMITC(t);
01034           break;
01035 
01036         default:
01037           break;
01038         }
01039       }
01040     }
01041   }
01042   while ((binumber == BUFFSIZE) || (biact < binumber));
01043 
01044   BCLOSE(spfp);
01045   qfprintf(ERR_STREAM,"]");
01046 }
01047 
01048 /* This function closes all open files */
01049 void
01050 #if NeedFunctionPrototypes
01051 CloseFiles(void)
01052 #else
01053 CloseFiles()
01054 #endif
01055 {
01056   struct font_entry *fe;
01057   FILEPTR f;
01058 
01059   /* First input/output files */
01060   if (outfp != FPNULL) {
01061 #ifdef RISC_BUFFER
01062     b_oflush(outfp);
01063 #endif
01064     BCLOSE(outfp);
01065   }
01066   if (dvifp != FPNULL) {
01067     BCLOSE(dvifp);
01068   }
01069 #ifdef __riscos
01070   if (metafile != FPNULL) {
01071     BCLOSE(metafile);
01072   }
01073 #endif
01074   /* Now all open font files */
01075   fe = hfontptr;
01076   while (fe != NULL) {
01077     f = fe->font_file_id;
01078     if ((f != FPNULL) && (f != NO_FILE)) {
01079       BCLOSE(f);
01080     }
01081     fe = fe->next;
01082   }
01083 }
01084 
01085 /*-->GetBytes*/
01086 /**********************************************************************/
01087 /*****************************  GetBytes  *****************************/
01088 /**********************************************************************/
01089 /* get n bytes from file fp; now a macro, so we don't need it any more
01090 void
01091 GetBytes(FILEPTR fp, char *cp, int n)
01092 {
01093   read_multi(cp,n,1,fp);
01094 }
01095 */
01096 
01097 /*-->NoSignExtend*/
01098 /**********************************************************************/
01099 /***************************  NoSignExtend  ***************************/
01100 /**********************************************************************/
01101 long4
01102 #if NeedFunctionPrototypes
01103 NoSignExtend(FILEPTR fp, register int n)
01104 #else
01105 NoSignExtend(fp, n)     /* return n byte quantity from file fd */
01106 register FILEPTR fp;    /* file pointer    */
01107 register int    n;      /* number of bytes */
01108 #endif
01109 {
01110   long4 x = 0;      /* number being constructed */
01111   unsigned char h;
01112   while (n--) {
01113     x <<= 8; 
01114     read_byte(fp,h);
01115     x |= h;
01116   }
01117   /* fprintf(stderr,"[%ld] ",(long)x);*/
01118   return(x);
01119 }
01120 
01121 
01122 #ifndef ARITHMETIC_RIGHT_SHIFT
01123 long4   signTab[5] = {0,0x00000080,0x00008000,0x00800000,0x00000000};
01124 long4 extendTab[5] = {0,~0^0xff,~0^0xffff,~0^0xffffff,~0^0xffffffff};
01125 #endif
01126 
01127 /*-->SignExtend*/
01128 /**********************************************************************/
01129 /****************************  SignExtend  ****************************/
01130 /**********************************************************************/
01131 long4
01132 #if NeedFunctionPrototypes
01133 SignExtend(FILEPTR fp, register int n)
01134 #else
01135 SignExtend(fp, n)     /* return n byte quantity from file fd */
01136 register FILEPTR fp;  /* file pointer    */
01137 register int     n;   /* number of bytes */
01138 #endif
01139 {
01140   int     n1;       /* number of bytes      */
01141   long4   x;        /* number being constructed */
01142   unsigned char    h;
01143 #ifdef SIGN_DEBUG
01144   long4    x0;      /* copy of x  */
01145 #endif
01146   read_byte(fp,h); 
01147   x = h; /* get first (high-order) byte */
01148   n1 = n--;
01149   while (n--) {
01150     x <<= 8;
01151     read_byte(fp,h);
01152     x |= h;
01153   }
01154   /*
01155    *   NOTE: This code assumes that the right-shift is an arithmetic, rather
01156    *   than logical, shift which will propagate the sign bit right.   According
01157    *   to Kernighan and Ritchie, this is compiler dependent!
01158    */
01159 
01160 #ifdef SIGN_DEBUG
01161   x0 = x;
01162 #endif
01163 
01164 #ifdef ARITHMETIC_RIGHT_SHIFT
01165   x <<= 32 - 8 * n1;
01166   x >>= 32 - 8 * n1; /* sign extend */
01167 #else
01168   if (x & signTab[n1]) x |= extendTab[n1];
01169 #endif
01170 
01171 #ifdef SIGN_DEBUG
01172   fprintf(ERR_STREAM,"\tSignExtend(fp,%d)=%lX, was=%lX,%d\n",
01173           n1,x,x0,x0&signTab[n1]);
01174 #endif
01175 
01176 #ifdef DEBUG
01177   if (Debug > 1)
01178     fprintf(ERR_STREAM,"\tSignExtend(fp,%d)=%lX\n", n1, x);
01179 #endif
01180   return(x);
01181 }
01182 
01183 
01184 #ifdef IBM3812
01185 /*-->PMPout*/
01186 /*****************************************************************************/
01187 /* This routine produces the PMP-envelopes for the 3812. Its semantics are:
01188 
01189    first arg == 0  ... flush buffer
01190    first arg == -1 ... number of bytes specified in the second argument
01191                have to be continuous, that is they must not
01192                be disrupted by ENTER PMP etc.
01193    first arg > 0       output first arg bytes
01194 
01195                If arg2 > OUTBUFSIZE ... flush buffer,
01196                         switch to unbuffered mode
01197                         (dont't collect PMP commands)
01198                If arg2+bufferpointer > OUTBUFSIZE ... flush buffer,
01199                         block will fit into buffer
01200                otherwise ..... block will fit into buffer
01201 
01202   Buffering is done to reduce the ENTER PMP-commands. Initially
01203   the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is
01204   necessary to enter PMP mode. The ENTER-PMP-command contains the
01205   number of bytes that will be interpreted as PMP-commands. In the
01206   most naive approach for each primitive command (eg. set cursor) you
01207   have to produce a seperate ENTER-PMP-envelope (5 bytes). It is
01208   favourable to collect as many PMP commands as possible in one envelope. */
01209 /*****************************************************************************/
01210 void
01211 #if NeedFunctionPrototypes
01212 PMPout(int l, char *s)
01213 #else
01214 PMPout(l, s)
01215 int     l;
01216 char    *s;
01217 #endif
01218 {
01219   static char           buffer[OUTBUFSIZE];
01220   static unsigned short bp = 0;         /* range 0..OUTBUFSIZE */
01221   static long4          continuous = 0l;
01222   static bool           buffered = _TRUE;
01223 
01224   if (l == 0) {
01225     if (bp == 0)
01226       return;
01227     EMIT3("\033[C%c%c", (unsigned char)(bp & 0xFF), (unsigned char)(bp >> 8));
01228     EMITB((int)bp, buffer);
01229     bp = 0;
01230     return;
01231   }
01232   if (l == -1) {
01233     continuous = (long4)s;
01234     if (continuous + (long4)bp + 5l > (long4)OUTBUFSIZE)
01235       PMPflush;
01236     buffered = (bool)((continuous + 5l <= (long4)OUTBUFSIZE));
01237     if (!buffered) {
01238       EMIT3("\033[C%c%c", (unsigned char)(continuous & 0xFF),
01239             (unsigned char)((continuous >> 8) & 0xFF));
01240     }
01241     return;
01242   }
01243   if (buffered) {
01244     register int    i;
01245     if ( ((long4)l + bp) > OUTBUFSIZE)
01246       PMPflush;
01247     for (i = 0; i < l; i++)
01248       buffer[bp+i] = s[i];
01249     bp += (unsigned short)l;
01250   } else {
01251     EMITB((int)l, s);
01252     buffered = (bool)((continuous -= (long4)l) <= 0);
01253   }
01254 }
01255 
01256 
01257 void
01258 #if NeedFunctionPrototypes
01259 PMPoutC(char c)
01260 #else
01261 PMPoutC(c)
01262 char c;
01263 #endif
01264 {
01265   PMPout(1, &c);
01266 }
01267 #endif /* IBM3812 */
01268 
01269 
01270 #ifdef MSC5
01271 /*-->AssureBinary*/
01272 /**********************************************************************/
01273 /*************************** AssureBinary *****************************/
01274 /**********************************************************************/
01275 /* This procedure is both DOS AND MSC dependent. The MSC file open on */
01276 /* a device ignores the 'binary' of the "wb" parameter and opens the  */
01277 /* file in ascii mode. This procedure sets the file f to binary mode  */
01278 /* if it is connected to a device that is not console input or output */
01279 /* or the null device. For other operating systems this routine is    */
01280 /* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */
01281 /**********************************************************************/
01282 void
01283 #if NeedFunctionPrototypes
01284 AssureBinary(FILEPTR f)
01285 #else
01286 AssureBinary(f)
01287 FILEPTR f;
01288 #endif
01289 {
01290   union REGS regs;                      /* registers for bios call */
01291 
01292   regs.h.ah = (unsigned char) 0x44;     /* IOCTL                   */
01293   regs.h.al = (unsigned char) 0x00;     /* get device information  */
01294   regs.x.bx = (unsigned int) fileno(f); /* handle from MSC         */
01295   intdos(&regs, &regs);                 /* call DOS interrupt      */
01296                                         /* ---> result in DX       */
01297 
01298   if (  (regs.h.dl & 0x80)              /* file handle points to a device */
01299         && !(regs.h.dl & 0x07) ) {      /* neither console i/o or null    */ 
01300 
01301     regs.h.dl  |= 0x20;                 /* set BINARY bit in device info  */
01302     regs.h.ah = (unsigned char) 0x44;   /* IOCTL                  */
01303     regs.h.al = (unsigned char) 0x01;   /* set device information */
01304     regs.x.bx = (unsigned int) fileno(f); /* handle from MSC      */
01305     regs.h.dh = (unsigned char) 0x00;   /* clear DH               */
01306     intdos(&regs, &regs);               /* call DOS interrupt     */
01307   }
01308 }
01309 #endif /* MSC5 */
01310 
01311 /*------------------------ end dviIO.c ----------------------------------*/
01312 
01313 /*------------------------ begin dvichars.c -----------------------------*/
01314 /*-->EmitChar*/
01315 /**********************************************************************/
01316 /****************************  EmitChar  ******************************/
01317 /**********************************************************************/
01318 void                     /* output a character bitmap */
01319 #if NeedFunctionPrototypes
01320 EmitChar(long4 c, struct char_entry *ce)
01321 #else
01322 EmitChar(c, ce)
01323 long4    c;
01324 struct char_entry *ce;
01325 #endif
01326 {
01327   register int i;
01328   register unsigned char  *sl;
01329   unsigned short nbpl, nwpl;
01330   long     total;
01331 #ifdef LJ
01332   unsigned char cnv_buffer[10];
01333 #endif
01334 
01335 
01336 #ifdef LJ
01337 /*
01338 printf("Emit character %c(%d) id=%d, yoff=%d[%d], w=%d[%d], h=%d[%d]\n",
01339         (char)c,(int)c,
01340     fontptr->plusid,
01341     ce->yOffset, fontptr->max_yoff,
01342     ce->width,   fontptr->max_width,
01343     ce->height,  fontptr->max_height
01344 );
01345 */
01346 #endif
01347 
01348 
01349 
01350   if ( fontptr->ncdl == 0 ) {
01351 #ifdef IBM3812
01352     used_fontstorage += 1028;
01353 #endif
01354 #ifdef LJ
01355     if (fontptr->max_width == 0) { /* we have no realistic values */
01356       fontptr->max_yoff = CHAR_HEIGTH_LARGE;
01357       fontptr->max_width = CHAR_WIDTH_LARGE;
01358       fontptr->max_height = CHAR_HEIGTH_LARGE*2;
01359     }
01360 
01361     /* open font dict before first char, set active font */
01362     INT_ASCII(cnv_buffer,fontptr->plusid);
01363 # ifdef LJ4
01364     EMIT2("\033*c%sD\033)s68W", cnv_buffer);
01365     EMITB(6, "\0\104\024\2\0\0");
01366 # else
01367     EMIT2("\033*c%sD\033)s64W", cnv_buffer); /* changed 26 to 64 (khk) */
01368     EMITWORD( 64 );                     /* Font descriptor size */
01369     EMITC((char) 0 );                   /* res0 (byte) */
01370 #  ifdef SEVENBIT
01371     EMITC((char) 1);                    /* Font Type */
01372 #  else
01373     EMITC((char) 2);                    /* Font Type */
01374 #  endif /* SEVENBIT */
01375     EMITWORD( 0 );                      /* res1 */
01376 # endif /* LJ 4 */
01377     EMITWORD( fontptr->max_yoff);       /* Baseline Distance */
01378     EMITWORD( fontptr->max_width);      /* Cell Width */
01379     EMITWORD( fontptr->max_height);     /* Cell Height */
01380     EMITC((char) 0);            /* Orientation */
01381     EMITC((char) 1);            /* Spacing */
01382     EMITWORD( 277 );            /* Symbol Set */
01383     EMITWORD( 1024 );           /* Pitch */
01384     EMITWORD( 1024 );           /* Height */
01385     EMITWORD( 0 );              /* xHeight */
01386     EMITC((char) 0);            /* Width Type */
01387     EMITC((char) 0);            /* Style */
01388     EMITC((char) 0);            /* Stroke Weight */
01389     EMITC((char) 0);            /* Typeface */
01390     EMITC((char) 0);            /* res2 (byte) */
01391     EMITC((char) 0);            /* Serif Style */
01392     EMITWORD( 0 );              /* res 3 */
01393     EMITC((char) 0);            /* Underline Distance */
01394     EMITC((char) 0);            /* Underline Height */
01395     EMITWORD( 0 );              /* Text Height */
01396     EMITWORD( 0 );              /* Text Width */
01397     EMITWORD( 0 );              /* res4 */
01398     EMITWORD( 0 );              /* res5 */
01399     EMITC((char) 0);            /* Pitch Extended */
01400     EMITC((char) 0);            /* Height Extended */
01401     EMITWORD( 0 );              /* res6 */
01402     EMITWORD( 0 );              /* res7 */
01403     EMITWORD( 0 );              /* res8 */
01404     EMITB(16,"                ");
01405 # ifdef LJ4
01406     EMITB(4 ,"\2\130\2\130");
01407 # endif
01408     EMIT1("\033*c4F");
01409 #endif /* LJ */
01410     }
01411   if ( fontptr != prevfont ) {   /* because this isn't done on pass 0 */
01412 #ifdef LJ
01413     INT_ASCII(cnv_buffer,fontptr->plusid);
01414     EMIT2("\033(%sX", cnv_buffer);
01415 #endif
01416     prevfont = fontptr;
01417   }
01418 
01419 #ifdef USEPXL
01420   if (fontptr->id == pk89) {
01421     nwpl = 0; /* initialize variable */
01422     nbpl = ((int)(ce->width) +  7) >> 3;
01423     total = (long)ce->height * nbpl;
01424   } else if (fontptr->id == id1002) {
01425     nwpl = 0; /* initialize variable */
01426     nbpl = ((int)(ce->width) +  7) >> 3;
01427     total = (long)ce->height * nbpl;
01428   } else if (fontptr->id == id1001) {
01429     nwpl = ((int)(ce->width) + 31) >> 5;
01430     nbpl = ((int)(ce->width) + 7) >> 3;
01431     total = (long)ce->height * nbpl;
01432   } else {
01433     /* should never be necessary */
01434     nwpl = 0;
01435     nbpl = 0;
01436     total = 0;
01437   }
01438 #else
01439   nbpl = (num_cols + 7) >> 3;
01440   total = num_rows * nbpl;
01441 #endif
01442 /***************************************************************
01443     if ( ((char) c == 'i') && (fontptr->plusid == 0)) {
01444         long j;
01445         fprintf(ERR_STREAM, "cols=%ld, ncols=%ld\n",(long)nwpl,(long)nbpl);
01446 
01447         fprintf(ERR_STREAM, "%ld Bytes:->",(long)total);
01448         for (j=0; j<total; j++) {
01449             char *ch; char ic;
01450             ch = (char *)(ce->where.address.pixptr);
01451             ic = *(ch+j);
01452             fprintf(ERR_STREAM,"%X.",ic);
01453                 }
01454         fprintf(ERR_STREAM,"<- Now Emitting\n");
01455         }
01456 ***************************************************************/
01457 #ifdef USEPXL
01458 #ifdef IBM3812
01459   if ((short)(ce->height) - ce->yOffset > 55) {
01460     ce->yyOffset = (short) ce->height - ce->yOffset;
01461     ce->yOffset  = (short) ce->height;
01462   } else {
01463     ce->yyOffset = (short) 0;
01464   }
01465 #endif
01466 #ifdef LJ
01467   ce->yyOffset = (short) 0;
01468 #endif
01469 #endif
01470 
01471   /* ce->cw = (long4)(((double)ce->tfmw / (double)hconv) +0.5); */
01472   /* set active font to nn, load font pattern  xx ... */
01473 #ifdef IBM3812
01474   PMPcont(total + 9);
01475 # ifdef USEPXL
01476   sprintf(PMPformat, "\323%c\360%c%c%c",
01477           (unsigned char)fontptr->plusid,
01478           (unsigned char)VisChar((char)c),
01479           (unsigned char)ce->height,
01480           (unsigned char)ce->width);
01481   PMPout(6, PMPformat);
01482   PMPoutC((char)(-(ce->xOffset)));
01483   PMPoutC((char)(ce->cw - (-ce->xOffset + ce->width)));
01484   PMPoutC((char)(ce->yOffset));
01485 # else
01486   sprintf(PMPformat, "\323%c\360%c%c%c",
01487           (unsigned char)fontptr->plusid,
01488           (unsigned char)VisChar((char)c),
01489           (unsigned char)num_rows,
01490           (unsigned char)num_cols);
01491   PMPout(6, PMPformat);
01492   PMPoutC((char)(-x_offset));
01493   PMPoutC((char)(ce->cw - (-x_offset + num_cols)));
01494   PMPoutC((char)num_rows-y_offset);
01495 # endif
01496 #endif
01497 
01498 #ifdef LJ
01499 # ifdef LJ4
01500   if (CompressFontMode) { /* Should we use compressed font downloading? */
01501     /* For COMPRESSED CHARS */
01502     if (PrevSize < nbpl) {
01503       PrevSize = nbpl;
01504       if (PrevLine != NULL) 
01505         free(PrevLine);
01506       if ((PrevLine = (unsigned char*)malloc(PrevSize*sizeof(char))) 
01507           == NULL) {
01508         PrevSize = 0; 
01509         Fatal("EmitChar: Out of memory error!\n");
01510       }
01511     }
01512     /* Clear seed line */
01513     for (i = 0; i<nbpl; i++) 
01514       PrevLine[i] = 0;
01515     CChar_Off = 0; 
01516     CChar_Last = -1;
01517     
01518     /* This bit copied from below... */
01519 #  ifdef USEPXL
01520     if (fontptr->id == pk89)
01521       PkRaster(ce,2);
01522     else if (fontptr->id == id1002)
01523       for (i = 0; i < (int)ce->height; i++) {
01524         sl = ((unsigned char *)(ce->where.address.pixptr) + i * nbpl);
01525         CompressedCharLine(ce,nbpl,sl);
01526       }
01527     else if (fontptr->id == id1001)
01528       for (i = 0; i < (int)ce->height; i++) {
01529         sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
01530         CompressedCharLine(ce,nbpl,sl);
01531       }
01532 #  else
01533     for (i = num_rows; i > 0; i--) 
01534       CompressedCharLine(ce,nbpl,(bits + (i-1)*nbpl));
01535 #  endif /* USEPXL */
01536   }
01537   else 
01538     CChar_Off = -1;
01539 # endif /* LJ4 */
01540 
01541   INT_ASCII(cnv_buffer,fontptr->plusid);
01542   /* Depending on whether character could be packed or not the header looks
01543      different! */
01544 # ifdef LJ4
01545   /* printf("raw: %d (%d * %d), comp: %d\n",
01546      total,ce->width,ce->height,CChar_Off); */
01547   /* Characters that don't compress well are usually rather small so 
01548      reading them again and writing them uncompressed won't take 
01549      much time anyway. */
01550   if (CChar_Off > total) 
01551     CChar_Off = -1;
01552   if (CChar_Off >= 0) {
01553     EMIT4("\033*c%sd%dE\033(s%ldW", cnv_buffer,
01554           (unsigned int)VisChar((char)c), (long)(CChar_Off + 16));
01555     EMITB(4, "\4\0\016\2");
01556   }
01557   else
01558 # endif
01559     {
01560       EMIT4("\033*c%sd%dE\033(s%ldW", cnv_buffer,
01561             (unsigned int)VisChar((char)c), total + 16);
01562       EMITB(4, "\4\0\016\1");
01563     }
01564   /*    EMITC((char)(Landscape==_TRUE)); */
01565   EMITC((char)0);
01566   EMITC((char)0);
01567 #ifdef USEPXL
01568   EMITWORD(-ce->xOffset);
01569   EMITWORD(ce->yOffset);
01570   EMITWORD(ce->width);
01571   EMITWORD(ce->height);
01572 #else
01573   EMITWORD(-x_offset);
01574   EMITWORD(num_rows-y_offset);
01575   EMITWORD(num_cols);
01576   EMITWORD(num_rows);
01577 #endif
01578   EMITWORD((int)ce->cw * 4);
01579 #endif
01580 
01581 #ifdef LJ4
01582   /* Now output compressed or uncompressed */
01583   if (CChar_Off >= 0) {
01584     EMITL(CChar_Off,buffin); /* Could compress character into buffer */
01585   }
01586   else /* Couldn't compress character - output literally */
01587 #endif
01588 
01589     {
01590 #ifdef USEPXL
01591       if (fontptr->id == pk89)
01592         PkRaster(ce, 0);
01593       else if (fontptr->id == id1002)
01594         for (i = 0; i < (int)ce->height; i++) {
01595           sl = ((unsigned char *)(ce->where.address.pixptr) + i * nbpl);
01596           EMITL(nbpl, (char *)sl);
01597         }
01598       else if (fontptr->id == id1001)
01599         for (i = 0; i < (int)ce->height; i++) {
01600           sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
01601           EMITL(nbpl, (char *)sl);
01602         }
01603 #else
01604       for (i = num_rows; i > 0; i--) {
01605         EMITL (nbpl, bits + (i-1) * nbpl);
01606       }
01607 #endif
01608     }
01609     
01610 #ifdef IBM3812
01611 #ifdef USEPXL
01612   used_fontstorage += (long4)ce->height * ((ce->width + 15) >> 4) * 2 + 14;
01613 #else
01614   used_fontstorage += (long4)num_rows * ((num_cols + 15) >> 4) * 2 + 14;
01615 #endif
01616 #endif
01617 #ifdef LJ
01618 #ifdef USEPXL
01619   used_fontstorage += 64 * (((int)((ce->height * ce->width) - 1) / 64) + 1);
01620 #else
01621   used_fontstorage += 64 * ((((num_rows * num_cols) - 1) / 64) + 1);
01622 #endif
01623 #endif
01624   fontptr->ncdl += 1;
01625   G_ncdl += 1;
01626 }
01627 
01628 /*-->PkRaster*/
01629 /*********************************************************************/
01630 /**************************** PkRaster *******************************/
01631 /*********************************************************************/
01632 
01633 #ifdef USEPXL
01634 unsigned char getnyb (
01635 #if NeedFunctionPrototypes
01636                       void
01637 #endif
01638 );
01639 
01640 long4 pk_packed_num (
01641 #if NeedFunctionPrototypes
01642                       void
01643 #endif
01644 );
01645 
01646 #define  PKBYTE   *pkloc; pkloc ++
01647 #define  OUTCHAR(c) raster_line_buf[bp]= (unsigned char)c; bp++
01648 
01649 unsigned char   bitweight, inputbyte;
01650 unsigned char   dyn_f;
01651 unsigned char   *pkloc;
01652 int     repeatcount;
01653 
01654 void             /* <Read and translate raster description@>*/
01655 #if NeedFunctionPrototypes 
01656 PkRaster(struct char_entry *ce, int raster)
01657 #else
01658 PkRaster(ce, raster)
01659 struct char_entry *ce;
01660 int raster;
01661 #endif
01662 {
01663   int     rp;
01664   int     current_line;
01665   int     wordwidth;
01666   bool turnon;
01667   unsigned short  nbpl;
01668   long4    rowsleft, word, wordweight, hbit, count, i, j, tl;
01669   long4    row[101];
01670   unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
01671   unsigned short  bp;
01672 
01673 
01674   if (ce->charsize == HUGE_SIZE)
01675     Fatal( "cannot process currently PK font patterns of that size!\n");
01676 
01677 
01678   current_line = 0;
01679   pkloc = (unsigned char *)ce->where.address.pixptr;
01680   dyn_f = (unsigned char)(ce->flag_byte >> 4);
01681   turnon = (bool)((ce->flag_byte & 8) == 8);
01682   wordwidth = (int)(ce->width + 31) >> 5;
01683   nbpl = ((int)(ce->width) +  7) >> 3;
01684 
01685   bitweight = 0;
01686   if (dyn_f == 14) {
01687     /*printf("<Get raster by bits@>\n");*/
01688     for (i = 1; i <= (long4)ce->height; i++) {
01689       word = 0;
01690       wordweight = 31;
01691       bp = 0;            /* Sowa */
01692 
01693 #ifdef DRAWGLYPH
01694       printf("     |");
01695 #endif
01696       for (j = 1; j <= (long4)ce->width; j++) {
01697         bool getbit;
01698         /* bp = 0;               SOWA */
01699         /*******************************************begin Getbit *********/
01700         bitweight /= 2;
01701         if ( bitweight == 0 ) {
01702           inputbyte = PKBYTE;
01703           bitweight = 128;
01704         }
01705         getbit = (bool)
01706           ( inputbyte >= bitweight );
01707         if ( getbit )
01708           inputbyte -= bitweight;
01709         /*********************************************end Getbit *********/
01710 
01711         if (getbit)
01712           word += power[wordweight];
01713 
01714         wordweight --;
01715         if (wordweight == -1) {
01716 
01717 #ifdef DRAWGLYPH
01718           { int k;
01719           for (k = 31; k>=0; k--) {
01720             if ((power[k] & word)!=0) printf("M");
01721             else printf(".");
01722           }
01723           }
01724 #endif
01725 
01726           OUTCHAR((word >> 24 & 0xFF));
01727           OUTCHAR((word >> 16 & 0xFF));
01728           OUTCHAR((word >> 8 & 0xFF));
01729           OUTCHAR((word    & 0xFF));
01730 
01731           word = 0;
01732           wordweight = 31;
01733         }
01734       }
01735       if (wordweight < 31) {
01736 #ifdef COMMENT
01737 # ifdef DRAWGLYPH
01738         { 
01739           int k;
01740           for (k = 15; k>=0; k--) {
01741             if ((power[k] & word)!=0) printf("Z");
01742             else printf(":");
01743           }
01744         }
01745         printf("|\n ----|");
01746 # endif
01747 #endif
01748 
01749         for (j = 3; j >= (wordwidth * 4 - (long4)nbpl); j--) {
01750           OUTCHAR(((word >> (j << 3)) & 0xff));
01751 #ifdef DRAWGLYPH
01752           { 
01753             int k;
01754             for (k = 7; k>=0; k--) {
01755               if ((power[k] & ((word >> (j << 3)) & 0xff))!=0) printf("M");
01756               else printf(".");
01757             }
01758           }
01759 #endif
01760         }
01761 
01762       }
01763         
01764       switch (raster) {
01765       case 1: 
01766         RasterLine(ce, nbpl, current_line, raster_line_buf);
01767         current_line++;
01768         break;
01769 #ifdef LJ4
01770       case 2:
01771         CompressedCharLine(ce,(unsigned int)nbpl,raster_line_buf);
01772         break;
01773 #endif
01774       default:
01775         EMITL(bp, (char *)raster_line_buf);
01776       }
01777 
01778 #ifdef DRAWGLYPH
01779       printf("|\n");
01780 #endif
01781     }
01782   } else {
01783     /* fprintf(ERR_STREAM, "@<Create normally packed raster@>\n"); */
01784     rowsleft = (long4)ce->height;
01785     hbit = (long4)ce->width;
01786     repeatcount = 0;
01787     wordweight = 32;
01788     word = 0;
01789     rp = 1;
01790     while ( rowsleft > 0 ) {
01791       count = pk_packed_num();
01792       bp = 0;
01793 
01794       while (count > 0) {
01795         if ((count < wordweight) && (count < hbit)) {
01796           if (turnon)
01797             word +=
01798               gpower[wordweight] -
01799               gpower[wordweight - count];
01800 
01801           hbit -= count;
01802           wordweight -= count;
01803           count = 0;
01804         } else if ((count >= hbit) && (hbit <=
01805                                        wordweight)) {
01806 
01807           if (turnon)
01808             word +=
01809               gpower[wordweight] -
01810               gpower[wordweight - hbit];
01811 
01812           row[rp] = word;
01813 
01814           /*fprintf(ERR_STREAM, " @<Send row@> \n");*/
01815           for (i = 0; i <= (long4)repeatcount; i++) { int ii;
01816 
01817 #ifdef DRAWGLYPH
01818           printf("***  |");
01819 #endif
01820           for (ii = 1; ii < wordwidth; ii++) {
01821             tl = row[ii];
01822 
01823             OUTCHAR((tl >> 24 & 0xFF));
01824             OUTCHAR((tl >> 16 & 0xFF));
01825             OUTCHAR((tl >> 8  & 0xFF));
01826             OUTCHAR((tl       & 0xFF));
01827 
01828 #ifdef DRAWGLYPH
01829             { 
01830               int k;
01831               for (k = 31; k>=0; k--) {
01832                 if ((power[k] & row[ii])!=0) printf("M");
01833                 else printf(".");
01834               }
01835             }
01836 #endif
01837           }
01838           tl = row[wordwidth];
01839           for (j = 3; j >= (wordwidth *4 - (long4)nbpl); j--) {
01840             OUTCHAR(((tl >> (j << 3)) & 0xff));
01841 #ifdef DRAWGLYPH
01842             { 
01843               int k;
01844               for (k = 7; k>=0; k--) {
01845                 if ((power[k] & ((tl >> (j << 3)) & 0xff))!=0) printf("M");
01846                 else printf(".");
01847               }
01848             }
01849 #endif
01850           }
01851 
01852           switch (raster) {
01853           case 1: 
01854             RasterLine(ce, (unsigned int)nbpl, current_line, raster_line_buf);
01855             current_line++;
01856             break;
01857 #ifdef LJ4
01858           case 2:
01859             CompressedCharLine(ce,(unsigned int)nbpl,raster_line_buf);
01860             break;
01861 #endif
01862           default:
01863             EMITL(bp, (char *)raster_line_buf);
01864           }
01865 
01866           bp = 0;
01867 
01868 #ifdef DRAWGLYPH
01869           printf("|  ");
01870           for (j = 1; j <= (long4)wordwidth; j++) printf("%02lX/",row[j]);
01871           printf(" raster=%d\n",raster);
01872 #endif
01873           }
01874 
01875           rowsleft -=  (long4)repeatcount + 1;
01876           repeatcount = 0;
01877           rp = 1;
01878           word = 0;
01879           wordweight = 32;
01880           count -= hbit;
01881           hbit = (long4)ce->width;
01882         } else {
01883           if (turnon) word += gpower[wordweight];
01884           row[rp] = word;
01885           rp = rp + 1;
01886           word = 0;
01887           count -= wordweight;
01888           hbit -= wordweight;
01889           wordweight = 32;
01890         }
01891       }   /* .....while count > 0 */
01892       if (turnon)
01893         turnon = _FALSE;
01894       else
01895         turnon = _TRUE;
01896     } /* ...... rowsleft > 0 */
01897     if ((rowsleft != 0) || (hbit != (long4)ce->width))
01898       Fatal("Bad pk file----more bits than required!\n");
01899   } /* .... create normally packed raster */
01900 }
01901 
01902 unsigned char getnyb(
01903 #if NeedFunctionPrototypes
01904                       void
01905 #endif
01906                       )
01907 {
01908   register unsigned char  temp;
01909   if ( bitweight == 0 ) {
01910     inputbyte = PKBYTE;
01911     bitweight = 16;
01912   }
01913   temp = inputbyte / bitweight;
01914   inputbyte -= temp * bitweight;
01915   bitweight /= 16;
01916   return ( temp );
01917 }
01918 
01919 
01920 long4 pk_packed_num(
01921 #if NeedFunctionPrototypes
01922                      void
01923 #endif
01924                      )
01925 { /*@<Packed number procedure@>= */
01926   register int    i;
01927   long4    j;
01928 
01929   i = (int)getnyb();
01930   if (i == 0) {
01931     do {
01932       j = (long4)getnyb();
01933       i++;
01934     } while (j == 0);
01935     while (i > 0) {
01936       j = j * 16 + (long4)getnyb();
01937       i--;
01938     };
01939     return (j - 15 + (13 - dyn_f) * 16 + dyn_f);
01940   } else if (i <= (int)dyn_f) {
01941     return ((long4)i);
01942   } else if (i < 14) {
01943     return ((i-(long4)dyn_f - 1) * 16 + (long4)getnyb() + dyn_f + 1);
01944   } else {
01945     if (i == 14) {
01946       repeatcount = (int)pk_packed_num();
01947     } else {
01948       repeatcount = 1;
01949     }
01950     /*     fprintf(ERR_STREAM,"repeatcount = [%d]\n",repeatcount);    */
01951     return (pk_packed_num());    /* tail end recursion !! */
01952   }
01953 }
01954 #endif
01955 
01956 #ifndef USEPXL
01957 void
01958 #if NeedFunctionPrototypes
01959 bad_gf(int n)
01960 #else
01961 bad_gf(int n)
01962 int n;
01963 #endif
01964 {
01965   Fatal("Bad gf file, case %d\n",n);      /* See gf.c */
01966 }
01967 #endif
01968 
01969 
01970 #ifdef LJ4
01971 /* Compress a raster line in compression mode 2 */
01972 int 
01973 #if NeedFunctionPrototypes
01974 CompressLine2(unsigned char *buffer, unsigned char *buffout, int emitbytes)
01975 #else
01976 CompressLine2(buffer, buffout, emitbytes)
01977 unsigned char *buffer;
01978 unsigned char *buffout;
01979 int emitbytes;
01980 #endif
01981 {
01982   unsigned char *pos,*ppos,*litpos,*upper;
01983   int lit,i,pack;
01984   char last,c;
01985 
01986   /* trap empty lines (otherwise problems with Packbits) */
01987   if (emitbytes == 0) 
01988     return(0);
01989   /* Use Packbits compression (mode 2) on raster line */
01990   pos = buffer; 
01991   litpos = buffer; 
01992   pack = 1; 
01993   ppos = buffout; 
01994   last = *pos++;
01995   upper = buffer + emitbytes;
01996   while (pos < upper) {
01997     c = *pos++;
01998     if (c == last) {
01999       pack++;
02000       /* At least three equal bytes ==> write out preceding literal sequence */
02001       if ((pack == 3) && ((lit = (int)(pos - litpos - 3)) != 0)) {
02002         while (lit >= 128) {
02003           *ppos++ = 127; 
02004           for (i = 1; i<=128; i++) 
02005             *ppos++ = *litpos++;
02006           lit -= 128;
02007         }
02008         if (lit != 0) {
02009           *ppos++ = lit-1; 
02010           while ((lit--) > 0) 
02011             *ppos++ = *litpos++;
02012           /* litpos is now pos-3 (i.e. first of the sequence) */
02013         }
02014       }
02015     }
02016     else {
02017       while (pack >= 128) {
02018         *ppos++ = 129; 
02019         *ppos++ = last; 
02020         litpos += 128; 
02021         pack -= 128;
02022       }
02023       /* At least 3 equal bytes or 2 that don't break a literal sequence
02024          ==> write out packed sequence */
02025       if ((pack >= 3) || ((pack == 2) && (litpos == pos-3))) {
02026         *ppos++ = 257 - pack; 
02027         *ppos++ = last; 
02028         litpos += pack;
02029       }
02030       pack = 1; 
02031       last = c;
02032     }
02033     if (ppos > (buffout + BUFFSIZE/2 - 129)) {
02034       fprintf(ERR_STREAM,
02035               "Can't compact raster character; rerun without compression!\n");
02036       return(0);
02037     }
02038   }
02039   
02040   while (pack >= 128) {
02041     *ppos++ = 129; 
02042     *ppos++ = last; 
02043     litpos += 128; 
02044     pack -= 128;
02045   }
02046   if ((pack >= 3) || ((pack == 2) && (litpos == pos-3))) {
02047     *ppos++ = 257 - pack; 
02048     *ppos++ = last; 
02049     litpos += pack;
02050   }
02051   else if ((lit = (int)(pos - litpos)) != 0) {
02052     while (lit >= 128) {
02053       *ppos++ = 127; 
02054       for (i = 1; i<=128; i++) 
02055         *ppos++ = *litpos++;
02056       lit -= 128;
02057     }
02058     if (lit != 0) {
02059       *ppos++ = lit-1; 
02060       while ((lit--) > 0) 
02061         *ppos++ = *litpos++;
02062     }
02063   }
02064   return((int)(ppos - buffout));
02065 }
02066 
02067 
02068 /* Compress a raster line in compression mode 3 */
02069 #if NeedFunctionPrototypes
02070 int CompressLine3(unsigned char *buffer, unsigned char *buffout, int emitbytes)
02071 #else
02072 int CompressLine3(buffer, buffout, emitbytes)
02073 unsigned char *buffer;
02074 unsigned char *buffout;
02075 int emitbytes;
02076 #endif
02077 {
02078   unsigned char *pos,*ppos,*litpos,*upper,*prev;
02079   int lit,i,pack;
02080 
02081   /* Use compression mode 3 */
02082   pos = buffer; 
02083   ppos = buffout; 
02084   upper = buffer + emitbytes; 
02085   prev = PrevLine;
02086   while(pos < upper) {
02087     litpos = pos;
02088     while ((*prev == *pos) && (pos < upper)) {
02089       prev++; 
02090       pos++;
02091     }
02092     if (pos < upper) {
02093       pack = (int)(pos - litpos); 
02094       litpos = pos;
02095       i = upper - pos; 
02096       if (i > 8) 
02097         i = 8;
02098       while ((*pos != *prev) && (i > 0)) {
02099         *prev++ = *pos++; 
02100         i--;
02101       }
02102       i = (int)(pos - litpos - 1);
02103       lit = i<<5;
02104       if (pack < 31) {
02105         *ppos++ = lit + pack;
02106       }
02107       else {
02108         *ppos++ = lit + 31; 
02109         pack -= 31;
02110         while (pack >= 255) {
02111           *ppos++ = 255; 
02112           pack -= 255;
02113         }
02114         *ppos++ = pack;
02115       }
02116       while (i >= 0) {
02117         *ppos++ = *litpos++; 
02118         i--;
02119       }
02120     }
02121     if (ppos > (buffout + BUFFSIZE/2 - 16)) {
02122       fprintf(ERR_STREAM,
02123               "Can't compact raster character; rerun without compression!\n");
02124       return(0);
02125     }
02126   }
02127   return((int)(ppos - buffout));
02128 }
02129 #endif
02130 
02131 /*-->RasterLine*/
02132 /**********************************************************************/
02133 /****************************  RasterLine  ****************************/
02134 /**********************************************************************/
02135 void
02136 #if NeedFunctionPrototypes
02137 RasterLine(struct char_entry *ce, unsigned int nbpl, 
02138            unsigned int current_line, unsigned char *buffer)
02139 #else
02140 RasterLine(ce, nbpl, current_line, buffer)
02141 struct char_entry *ce;
02142 unsigned short  nbpl, current_line;
02143 char *buffer;
02144 #endif
02145 {
02146 #ifdef IBM3812
02147   long   total;
02148   static unsigned short   maxlines;
02149 
02150   if (current_line == 0) {
02151 # ifdef USEPXL
02152     maxlines = ce->height;
02153 
02154     MoveVert(-ce->yOffset);      /* move cursor up */
02155     MoveHor(-ce->xOffset);       /* move cursor right */
02156 # else
02157     maxlines = num_rows;
02158 
02159     MoveVert(- (num_rows-y_offset) );      /* move cursor up */
02160     MoveHor(-x_offset);       /* move cursor right */
02161 # endif
02162     last_rx = last_ry = UNKNOWN;       /* next time full positioning */
02163   }
02164 
02165   if (current_line % maxlines == 0) {
02166     if (current_line > 0) {    /* maxlines lines have been printed*/
02167       MoveVert(maxlines);   /*   move cursor down     */
02168       last_rx = last_ry = UNKNOWN;    /* next time full positioning */
02169     }
02170 # ifdef USEPXL
02171     total = (long)(ce->height - current_line) * (long4)nbpl;
02172 # else
02173     total = (long)(num_rows - current_line) * (long4)nbpl;
02174 # endif
02175     if ((total + 9) > 65535) {
02176       maxlines = (unsigned short)((65535 - 9) / nbpl);
02177       total = (long)maxlines * (long)nbpl;
02178     }
02179 
02180     PMPcont(total + 9);
02181     PMPout(2, "\365\0");
02182     EMITWORD(maxlines);
02183 # ifdef USEPXL
02184     EMITWORD(ce->width);
02185 # else
02186     EMITWORD(num_cols);
02187 # endif
02188     PMPoutC((unsigned char) (total >> 16) & 0xFF);
02189     PMPoutC((unsigned char) (total >> 8 ) & 0xFF);
02190     PMPoutC((unsigned char)  total     & 0xFF);
02191   }
02192   EMITL((int)nbpl, (char *)buffer);
02193 #endif /* IBM3812 */
02194 
02195 
02196 #ifdef LJ
02197   register int emitbytes;
02198 #ifdef LJ4
02199   int i;
02200 #endif
02201 
02202   for (emitbytes = (int)nbpl;
02203        (*(buffer + emitbytes - 1) == '\0') && (emitbytes > 0);
02204        emitbytes--);
02205 # ifdef LJ4
02206   switch (CompressCharMode) {
02207   case 0:
02208     EMIT2("\033*b%dW", emitbytes);
02209     EMITL(emitbytes, buffer);
02210     break;
02211  
02212   case 2:
02213     i = CompressLine2(buffer,buffin,emitbytes);
02214     EMIT2("\033*b%dW", i);
02215     EMITL(i,buffin);
02216     break;
02217  
02218   case 3:
02219     i = CompressLine3(buffer,buffin + BUFFSIZE/2,(int)nbpl);
02220     EMIT2("\033*b%dW", i);
02221     EMITL(i,buffin + BUFFSIZE/2);
02222     break;
02223  
02224   default: 
02225     fprintf(ERR_STREAM,"Unsupported compression mode!\n"); 
02226   }
02227 # else
02228   EMIT2("\033*b%dW", emitbytes);
02229   EMITL(emitbytes, buffer);
02230 # endif /* LJ4 */
02231 #endif /* LJ */
02232 }
02233 
02234 
02235 /*-->RasterChar*/
02236 /**********************************************************************/
02237 /****************************  RasterChar  ****************************/
02238 /**********************************************************************/
02239 void                     /* raster a character bitmap */
02240 #if NeedFunctionPrototypes
02241 RasterChar(struct char_entry *ce)
02242 #else
02243 RasterChar(ce)
02244 struct char_entry *ce;
02245 #endif
02246 {
02247   int      i;
02248   register unsigned char  *sl;
02249   unsigned short  nbpl, nwpl;
02250   unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
02251 
02252 #ifdef DEBUG
02253   if (Debug)
02254     fprintf(ERR_STREAM,"Raster character ...size=%d \n", (int)ce->charsize);
02255 #endif
02256 
02257 #ifdef USEPXL
02258   if (fontptr->id == pk89) {
02259     nwpl = 0; /* initialize variable */
02260     nbpl = ((int)(ce->width) +  7) >> 3;
02261   } else if (fontptr->id == id1002) {
02262     nwpl = 0; /* initialize variable */
02263     nbpl = ((int)ce->width +  7) >> 3;
02264   } else if (fontptr->id == id1001) {
02265     nwpl = ((int)ce->width + 31) >> 5;
02266     nbpl = ((int)ce->width + 7) >> 3;
02267   } else {
02268     /* should never be necessary */
02269     nwpl = 0;
02270     nbpl = 0;
02271   }
02272 #else
02273   nbpl = (num_cols + 7) >> 3;
02274 #endif
02275 
02276 #ifdef LJ
02277 # ifdef LJ4
02278   CompressCharMode = (ce->width < CompressCharWidth) ? 0 : UseCompression;
02279   EMIT3("\033*t%dR\033*r1A\033*b%dM",RESOLUTION,CompressCharMode);
02280   if (CompressCharMode == 3) {
02281     /* Check if PrevLine big enough; claim more space if not */
02282     if (((int)nbpl) > PrevSize) {
02283       if (PrevLine != NULL) 
02284         free(PrevLine);
02285       if ((PrevLine = (unsigned char *)malloc(nbpl*sizeof(char))) == NULL) {
02286         PrevSize = 0; 
02287         Fatal("RasterChar: out of memory!\n");
02288       }
02289       PrevSize = (int)nbpl;
02290     }
02291     /* Clear previous line */
02292     sl = PrevLine;
02293     for (i = 0; i<nbpl; i++)
02294       *sl++ = 0;
02295   }
02296 # else
02297   EMIT2("\033*t%dR\033*r1A\033*b0M",RESOLUTION);
02298 # endif /* LJ4 */
02299 #endif
02300   { /* read pixel from file */
02301     if ((ce->charsize == HUGE_SIZE) && (fontptr->id != pk89))
02302       OpenFontFile();
02303 #ifdef USEPXL
02304     FSEEK(pxlfp, ce->where.address.fileOffset, SEEK_SET);
02305 #else
02306     FSEEK(gfin, ce->where.address.fileOffset, SEEK_SET);
02307     gettochar();
02308     readbits();
02309 #endif /* USEPXL */
02310   }
02311 
02312 #ifdef USEPXL
02313   if (fontptr->id == pk89)
02314     PkRaster(ce, 1);
02315   else if (fontptr->id == id1002) {
02316     for (i = 0; i < (int)ce->height; i++) {
02317       if (ce->charsize == HUGE_SIZE) {
02318         fread(raster_line_buf, 1, (int)nbpl, pxlfp);
02319         sl = raster_line_buf;
02320       } else
02321         sl = ((unsigned char *)(ce->where.address.pixptr)
02322               + i * nbpl);
02323       RasterLine(ce, (unsigned int)nbpl, i, sl);
02324     }
02325   } else if (fontptr->id == id1001) {
02326     long filediff;
02327     filediff = (long)nwpl * 4 - nbpl;
02328     for (i = 0; i < (int)ce->height; i++) {
02329       if (ce->charsize == HUGE_SIZE) {
02330         read_multi(raster_line_buf, 1, (int)nbpl, pxlfp);
02331         /* skip fill bytes */
02332         FSEEK(pxlfp, filediff, SEEK_CUR);
02333         sl = raster_line_buf;
02334       } else
02335         sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
02336       RasterLine(ce, (unsigned int)nbpl, i, sl);
02337     }
02338   }
02339 #else
02340   for (i = num_rows; i > 0; i--)
02341     RasterLine(ce, (unsigned int)nbpl, i, bits + (i-1) * nbpl);
02342 #endif
02343 #ifdef LJ
02344   EMIT1("\033*rB");
02345 #endif
02346   last_rx = last_ry = UNKNOWN;
02347 }
02348 
02349 /*-->LoadAChar*/
02350 /**********************************************************************/
02351 /***************************** LoadAChar ******************************/
02352 /**********************************************************************/
02353 void
02354 #if NeedFunctionPrototypes
02355 LoadAChar(long4 c, register struct char_entry *ptr)
02356 #else
02357 LoadAChar(c, ptr)
02358 long4    c;
02359 register struct char_entry *ptr;
02360 #endif
02361 {
02362   long4    *pr;
02363   long     bytes;
02364 
02365   if (ptr->where.address.fileOffset == NONEXISTANT
02366 #ifdef LJ_RESIDENT_FONTS
02367       || fontptr->resident_p
02368 #endif
02369       ) {
02370     ptr->where.isloaded = _FALSE;
02371     return;
02372   }
02373 
02374   OpenFontFile();
02375 
02376 #ifdef DEBUG
02377   if (Debug)
02378     fprintf(ERR_STREAM, "LoadAChar: <%c>(%ld) from file at pos %ld\n",
02379             (char)c,(long)c,(long)ptr->where.address.fileOffset);
02380 #endif
02381 
02382 #ifdef USEPXL
02383 
02384   FSEEK(pxlfp, ptr->where.address.fileOffset, SEEK_SET);
02385 
02386   if (fontptr->id == pk89) {
02387 #ifdef PARANOIA
02388     unsigned char   temp;
02389     temp = (unsigned char) NoSignExtend(pxlfp, 1);
02390 
02391     if ((int)(ptr->flag_byte) != (int)temp) {
02392       fprintf(ERR_STREAM,"font=%lx, ptr=%lx\n",fontptr,ptr);
02393       Fatal("%d: oh boy! old flag %d, new flag %d, ptr=%lx\n",
02394             (int)c,(int)(ptr->flag_byte),(int)temp,ptr);
02395     }
02396 #endif
02397 
02398     if ((ptr->flag_byte & 7) == 7) {
02399       bytes = NoSignExtend(pxlfp, 4) - 28;
02400       FSEEK(pxlfp, ptr->where.address.fileOffset + 36, SEEK_SET);
02401       /*
02402         fprintf(ERR_STREAM,"bytes=%d, seeking at %ld\n",
02403         bytes, ptr->where.address.fileOffset + 36);
02404         */
02405     } else if ((ptr->flag_byte & 4) == 4) {
02406       bytes = ((long4)ptr->flag_byte & 3) * 65536l + NoSignExtend(pxlfp, 2) - 13;
02407       FSEEK(pxlfp, ptr->where.address.fileOffset + 16, SEEK_SET);
02408     } else {
02409       bytes = ((long4)ptr->flag_byte & 3) * 256 + NoSignExtend(pxlfp, 1) - 8;
02410       FSEEK(pxlfp, ptr->where.address.fileOffset + 10, SEEK_SET);
02411     }
02412   } else if (fontptr->id == id1002)
02413     bytes =  ((( (long4)ptr->width + 7) >> 3) * (long4)ptr->height);
02414   else if (fontptr->id == id1001)
02415     bytes =  4 * (((long4)ptr->width + 31) >> 5) * (long4)ptr->height;
02416   else
02417     bytes = 0;
02418 
02419   if (bytes > 0) {
02420     /* do NOT load Huge characters */
02421     if ((bytes > HUGE_CHAR_PATTERN) && (fontptr->id != pk89)) {
02422       qfprintf(ERR_STREAM,"Huge Character <%c> (%ld Bytes)\n", 
02423                (char)c, bytes);
02424       ptr->charsize = HUGE_SIZE;
02425       ptr->where.isloaded = _FALSE;
02426     } else {
02427       if ( (pr = (long4 *)malloc( bytes )) == NULL )
02428         Fatal("Unable to allocate %ld bytes for char <%c>\n", bytes, (char)c);
02429       /*
02430        * else fprintf(ERR_STREAM,"allocating %ld bytes char <%c>(%d)\t at 0x%lx\n",
02431        *                      bytes, (char)c,(int)c,pr);
02432        */
02433 #ifdef DEBUG
02434       if (Debug)
02435         fprintf(ERR_STREAM,
02436                 "Allocating Char <%c>, FileOffset=%lX, Bytes=%ld (%d) <%d>\n",
02437                 (char)c, ptr->where.address.fileOffset, bytes,
02438                 (int)bytes, (unsigned int)bytes);
02439 #endif
02440       allocated_storage += bytes;
02441       read_multi(pr, 1, (int)bytes , pxlfp);
02442       ptr->where.address.pixptr = pr;
02443     }
02444   }
02445 #else
02446   FSEEK(gfin, ptr->where.address.fileOffset, SEEK_SET);
02447   gettochar();
02448   readbits();
02449   if (num_bytes > HUGE_CHAR_PATTERN)
02450     ptr->charsize = HUGE_SIZE;
02451 #endif
02452   ptr->where.isloaded = _TRUE;
02453   if (ptr->charsize != SMALL_SIZE
02454 #ifdef LJ
02455       /* we might have problems at the edge of the paper with diff. sized characters
02456        * the correct treatment would be to check whether the bounding box of
02457        * tfontptr is within the paper relative to the current position
02458        */
02459       || fontptr->max_height > CHAR_HEIGTH_LARGE
02460       || (rasterfont[fontptr->plusid])
02461 #endif
02462       )
02463     return;
02464 
02465   EmitChar(c, ptr);
02466 #ifdef USEPXL
02467   /* we should really free the space used by the PXL data after this
02468      point, but it is not large, and besides, we may want to be
02469      more clever in the future, about sending bitmaps.  So keep
02470      the data around */
02471 #endif
02472 }
02473 
02474 /*-->SetChar*/
02475 /**********************************************************************/
02476 /*****************************  SetChar  ******************************/
02477 /**********************************************************************/
02478 void
02479 #if NeedFunctionPrototypes
02480 SetChar(long4 c, short command, int PassNo, bool do_posn, bool in_string)
02481 #else
02482 SetChar(c, command, PassNo, do_posn,in_string)
02483 long4    c;
02484 short   command;
02485 int     PassNo;
02486 bool do_posn,in_string;
02487 #endif
02488 {
02489   register struct char_entry *ptr;  /* temporary char_entry pointer */
02490   bool pos_after = _FALSE;
02491 
02492   ptr = &(fontptr->ch[c]);
02493   if (!((ptr->where.isloaded) || (ptr->charsize == HUGE_SIZE)))
02494     LoadAChar(c, ptr);
02495   if (PassNo == 0)
02496     return;
02497 
02498   if (do_posn) {
02499 #ifdef IBM3812
02500     if (CharStringPos>0) {
02501       fprintf(ERR_STREAM,"!!!! That should never happen!!!\n");
02502       CharStringOut;
02503     }
02504 #endif
02505     SetPosn(h, v);
02506   }
02507 
02508   /*  
02509     fprintf(ERR_STREAM,
02510             "(%d) hh=%ld (+%ld/+%ld), h=%ld, xh=%ld,xhh=%ld, [%ld|%ld] ->%d\n",
02511             (int)do_posn,hh,(long4)ptr->cw,(long4)ptr->cw*(long4)hconv,h,
02512             (long)PIXROUND(h, hconv),
02513             (long)PIXROUND(hh, hconv),
02514             (long)labs((hh-h)),(long)hconv,
02515             (labs((hh-h))>hconv)
02516             );
02517             */
02518 
02519   if (in_string && (labs((hh-h))>hconv)) {
02520 #ifdef IBM3812
02521     CharStringOut;
02522 #endif
02523     SetPosn(h, v);
02524   }
02525 
02526   /*
02527     fprintf(ERR_STREAM,"raster?=%d - last_ry=%d, last_rx=%d,mmax-height=%d\n",
02528     (int)last_ry < fontptr->max_height, (int)last_ry,(int)last_rx,
02529     (int)fontptr->max_height);
02530     */
02531 
02532   if (fontptr->font_file_id != NO_FILE) {      /* ignore missing fonts */
02533     if (
02534 #ifdef LJ_RESIDENT_FONTS
02535         !fontptr->resident_p &&
02536 #endif
02537         (ptr->charsize != SMALL_SIZE
02538 #ifdef LJ
02539          /* the LaserJet cannot print characters
02540           * where the bounding box lies outside the
02541           * paper edge. Missing: right paper edge
02542           */
02543          || last_ry < (int)fontptr->max_height
02544          || fontptr->max_height > CHAR_HEIGTH_LARGE
02545          || (rasterfont[fontptr->plusid])
02546          || (brother_mode && c == 0)
02547 #ifdef SEVENBIT
02548          || (kyocera_mode && c == 32)
02549 #endif
02550 #endif
02551          )) {
02552 #ifdef LJ
02553       int     tmp;
02554       char    sign;
02555 
02556       if (!do_posn) 
02557         SetPosn(h, v);
02558 
02559 #ifdef USEPXL
02560       tmp = (int)-ptr->yOffset;
02561 #else
02562       tmp = (int)num_rows-y_offset;
02563 #endif
02564       if (tmp != 0) {
02565         if (tmp < 0) {
02566           sign = '-'; 
02567           tmp = -tmp;
02568         } else
02569           sign = '+';
02570         EMIT3("\033*p%c%dY", sign, tmp);
02571       }
02572 #ifdef USEPXL
02573       tmp = (int)-ptr->xOffset;
02574 #else
02575       tmp = (int)-x_offset;
02576 #endif
02577       if (tmp != 0) {
02578         if (tmp < 0) {
02579           sign = '-'; 
02580           tmp = -tmp;
02581         } else
02582           sign = '+';
02583         EMIT3("\033*p%c%dX", sign, tmp);
02584       }
02585 #endif
02586 #ifdef IBM3812
02587       CharStringOut;
02588 #endif
02589 #ifdef DEBUG
02590       if (Debug)
02591 #ifndef vms
02592         fprintf(ERR_STREAM,"Raster character <%c> %hd\n", (char) c,(short)c);
02593 #else
02594       fprintf(ERR_STREAM,"Raster character <%c> %d\n", (char) c,(short)c);
02595 #endif
02596 #endif
02597       RasterChar(ptr);
02598       pos_after = _TRUE;
02599     } else {
02600       unsigned char cc;
02601       cc = VisChar((char)c);
02602 #ifdef IBM3812
02603 #ifdef USEPXL
02604       if ( ptr->yyOffset || (!in_string) ) {
02605         CharStringOut;
02606         MoveVert(ptr->yyOffset);
02607         sprintf(PMPformat, "\01%c", cc);
02608         PMPout(2, PMPformat);
02609         MoveVert((int)-(ptr->yyOffset));
02610       } else {
02611 #endif
02612         if (CharStringPos==CHARSTRINGMAX)
02613           CharStringOut;
02614 
02615         CharString[CharStringPos] = cc;
02616         CharStringPos++;
02617 #ifdef USEPXL
02618       }
02619 #endif
02620 #endif
02621 #ifdef LJ
02622 #define TRANSPARENTCHAR(ch) \
02623       if ((ch == 0l) || (ch >= 7l && ch <= 15l) || (ch == 27l)) \
02624           EMIT2("\033&p1X%c", (unsigned char)ch); \
02625       else { EMITC((unsigned char)ch); }
02626 #ifdef USEPXL
02627       if (ptr->yyOffset) {
02628 #ifndef vms
02629         EMIT2("\033*p+%hdY", ptr->yyOffset);
02630         TRANSPARENTCHAR(cc);
02631         EMIT2("\033*p-%hdY", ptr->yyOffset);     /* GUGUGU 255 */
02632 #else
02633         EMIT2("\033*p+%dY", ptr->yyOffset);
02634         TRANSPARENTCHAR(cc);
02635         EMIT2("\033*p-%dY", ptr->yyOffset);     /* GUGUGU 255 */
02636 #endif
02637       } else
02638 #endif
02639         /*                EMITC( (unsigned char)c);*/
02640         { TRANSPARENTCHAR(cc);}
02641 #endif
02642     }
02643     /*
02644     fprintf(stderr,"--> hh(%ld) += cw(%ld) * hconv(%ld)",
02645             (long)hh, (long)ptr->cw, (long) hconv);
02646             */
02647 #ifdef LJ    
02648     /* the guessed position must be a multiple of pixels */
02649     if (RESOLUTION == 300)
02650       hh += (long4) ((ptr->cw)/4)*4*hconv;
02651     else /* RESOLUTION == 600 */
02652       hh += (long4) ((ptr->cw)/2)*2*hconv;
02653 #else
02654     hh += (long4)(ptr->cw * hconv);
02655 #endif
02656     /*
02657       fprintf(stderr," = hh(%ld)\n",(long)hh);
02658       */
02659   }
02660 
02661   if (command <= SET4)
02662     h += ptr->tfmw;
02663 
02664   if (pos_after) 
02665     SetPosn(h, v);
02666   else
02667     last_rx = (int)PIXROUND(h, hconv) + x_goffset;
02668 }
02669 
02670 #if NeedFunctionPrototypes
02671 void DoBop(void)
02672 #else
02673 void DoBop()
02674 #endif
02675 {
02676   struct font_entry *p;
02677 #ifdef LJ
02678   register short i;
02679   if (fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
02680     for (i = 0; i < HANDLE_MAX_FONTS; i++)
02681       rasterfont[i] = _FALSE;
02682   }
02683   fonts_used_on_this_page = 0;
02684 #endif
02685   for (p = hfontptr; p; p = p->next) 
02686     p->used_on_this_page = _FALSE;
02687 }
02688 
02689 /*-->SetString*/
02690 /**********************************************************************/
02691 /*****************************  SetString  ****************************/
02692 /**********************************************************************/
02693 void
02694 #if NeedFunctionPrototypes
02695 SetString(short firstch, int PassNo)
02696 #else
02697 SetString(firstch, PassNo)    /* read and set a consecutive string of chars */
02698 short   firstch;
02699 int     PassNo;
02700 #endif
02701 {
02702   short   c;
02703   register unsigned short i;
02704 
02705 #ifdef DEBUG
02706   if (Debug)
02707     fprintf(ERR_STREAM, "SetString ");
02708 #endif
02709   for (i = 0, c = firstch; c >= SETC_000 && c <= SETC_127; i++) {
02710 #ifdef DEBUG
02711     if (Debug)
02712       fprintf(ERR_STREAM, "%d(%c) ", c, c);
02713 #endif
02714     SetChar((long4)c, c, PassNo, (bool)(i==0), _TRUE);
02715     c = (short)NoSignExtend(dvifp, 1);
02716   }
02717   FSEEK(dvifp, -1l, SEEK_CUR);    /* backup one character */
02718 #ifdef IBM3812
02719   CharStringOut;
02720 #endif
02721 #ifdef DEBUG
02722   if (Debug)
02723     fprintf(ERR_STREAM, "...SetString\n");
02724 #endif
02725 }
02726 
02727 /*-->SetPosn*/
02728 /**********************************************************************/
02729 /*****************************  SetPosn  ******************************/
02730 /**********************************************************************/
02731 void                  /* output a positioning command */
02732 #if NeedFunctionPrototypes
02733 SetPosn(long4 x, long4 y)
02734 #else
02735 SetPosn(x, y)
02736 long4    x, y;
02737 #endif
02738 {
02739   int     rx, ry;
02740   rx = (int)PIXROUND(x, hconv) + x_goffset;
02741   ry = (int)PIXROUND(y, vconv) + y_goffset;
02742 
02743   /*  
02744   fprintf(ERR_STREAM,
02745          "setposn to %ld/%ld, %d/%d, last: %d/%d\n",
02746          (long)x,(long)y,
02747          rx,ry,
02748          last_rx,last_ry
02749       );
02750       */
02751 
02752 #ifdef IBM3812
02753   PMPcont(3);
02754   PMPoutC('\340');
02755   EMITWORD(LARGER(rx,0));
02756 
02757   if (last_ry != ry) { /* necessary to set new y-position */
02758     PMPcont(3);
02759     PMPoutC('\341');
02760     EMITWORD(LARGER(ry,0));
02761   }
02762 #endif
02763 #ifdef LJ
02764 #if 0
02765 /* this optimization doesn't work, as last_XX is set to the
02766    starting(!) position of the last string not to the end position! */
02767 
02768   if (last_rx != rx || last_ry != ry) {
02769     if (last_ry == ry)   /* not necessary to set new y-position */
02770       EMIT2("\033*p%dX", LARGER(rx,0));
02771     else if (last_rx == rx)
02772       EMIT2("\033*p%dY", LARGER(ry,0));
02773     else
02774       EMIT3("\033*p%dx%dY", LARGER(rx,0), LARGER(ry,0));
02775   }
02776 #endif
02777   if (last_ry == ry)   /* not necessary to set new y-position */
02778     EMIT2("\033*p%dX", LARGER(rx,0));
02779   else
02780     EMIT3("\033*p%dx%dY", LARGER(rx,0), LARGER(ry,0));
02781 #endif
02782 
02783   last_ry = ry;    /* last y-position on output device */
02784   last_rx = rx;    /* last x-position on output device */
02785   /*
02786    * must know where device "really" is horizontally, for rel. posning.
02787    * (maybe in the future), but we always use direct positioning for
02788    * vertical movement.
02789    */
02790   /* hh = rx * hconv; */
02791   hh = x;
02792   vv = y;
02793   /*
02794    * fprintf(ERR_STREAM,"DoPosn: x=%ld, y=%ld, rx=%d, ry=%d, hh=%ld, vv=%ld\n",
02795    *         (long)x,(long)y,rx,ry,(long)hh,(long)vv);
02796    */
02797 }
02798 
02799 
02800 
02801 #ifdef LJ4
02802 /* Compresses a rasterline of font data and appends it to buffin (used
02803    for storage of the compressed character). CChar_Off is the current
02804    offset in the buffer, CChar_Last is the first byte of the last
02805    compacted row (line repeat count).  Updates the previous line
02806    (PrevLine) if necessary. */
02807 void 
02808 #if NeedFunctionPrototypes
02809 CompressedCharLine(struct char_entry *ce, int nbpl, unsigned char *buffer)
02810 #else
02811 CompressedCharLine(ce, nbpl, buffer)
02812 struct char_entry *ce;
02813 int nbpl; 
02814 unsigned char *buffer;
02815 #endif
02816 {
02817   if (CChar_Off >= 0) {
02818     register unsigned char *obuf,*buff;
02819     unsigned char *prev,*end;
02820 #undef max /* cc thinks any max macro overrides a variable */
02821     int t,mode,max;
02822     register int x,y,i;
02823 
02824     prev = PrevLine; 
02825     obuf = buffer; 
02826     end = buffer + nbpl; 
02827     x = 0;
02828     while (obuf < end) {
02829       if (*obuf != *prev) {
02830         *prev = *obuf; 
02831         x = 1;
02832       }
02833       obuf++; 
02834       prev++;
02835     }
02836     if (x == 0 && CChar_Last >= 0) {
02837       (buffin[CChar_Last])++; 
02838       return; /* line repeat count +1 */
02839     }
02840 
02841     end = buffin + BUFFSIZE - 16; 
02842     obuf = buffin + CChar_Off; 
02843     buff = buffer;
02844     *obuf++ = 0; /* Line repeat count = 0 */
02845     t = 0;
02846     CChar_Last = CChar_Off; /* Next line */
02847     mode = 0; 
02848     y = *buff++; 
02849     i = 7; /* i = current bit */
02850     while ((t < ce->width) && (obuf < end)) {
02851       max = ce->width - t; /* maximum pixels left to do */
02852       x = 0;
02853       if (mode == 0) {
02854         /* white run */
02855         while ((y & (1<<i)) == 0 && x < max) {
02856           x++; 
02857           i--; 
02858           if (i < 0) {
02859             i = 7; 
02860             y = *buff++; 
02861             while (y == 0 && x < max) {
02862               x += 8; 
02863               y = *buff++;
02864             }
02865           }
02866         }
02867         mode = 1;
02868       }
02869       else {
02870         /* black run */
02871         while ((y & (1<<i)) != 0 && x < max) {
02872           x++; 
02873           i--; 
02874           if (i < 0) {
02875             i = 7; 
02876             y = *buff++; 
02877             while (y == 0xff && x < max) {
02878               x += 8; 
02879               y = *buff++;
02880             }
02881           }
02882         }
02883         mode = 0;
02884       }
02885       if (x > max) 
02886         x = max;
02887       t += x;
02888       /* make precautions for very long runs */
02889       while (x > 0xff) {
02890         *obuf++ = 0xff; 
02891         *obuf++ = 0; 
02892         x -= 0xff;
02893       }
02894       *obuf++ = x;
02895     }
02896     CChar_Off = obuf >= end ? -1 : obuf - buffin;
02897   }
02898 }
02899 #endif
02900 
02901 /*------------------------ end dvichars.c ------------------------------*/
02902 
02903 
02904 /* Report a warning if both checksums are nonzero, they don't match, and
02905    the user hasn't turned it off.  */
02906 
02907 static void
02908 check_checksum (c1, c2, name)
02909     unsigned c1, c2;
02910     const char *name;
02911 {
02912   if (c1 && c2 && c1 != c2
02913 #ifdef KPATHSEA
02914       && !kpse_tex_hush ("checksum")
02915 #endif
02916       ) {
02917      Warning ("Checksum mismatch in %s", name) ;
02918    }
02919 }
02920 
02921 
02922 /*------------------------ begin dviconv.c -----------------------------*/
02923 /*-->ActualFactor*/
02924 /**********************************************************************/
02925 /**************************  ActualFactor  ****************************/
02926 /**********************************************************************/
02927 double  /* compute the actual size factor given the approximation */
02928 #if NeedFunctionPrototypes
02929 ActualFactor(long4 unmodsize)
02930 #else
02931 ActualFactor(unmodsize)
02932 long4    unmodsize;                 /* actually factor * 1000 */
02933 #endif
02934 {
02935   double  realsize;     /* the actual magnification factor */
02936   realsize = (double)unmodsize / 1000.0;
02937   if (abs((int)(unmodsize - 1095l))<2)
02938     realsize = 1.095445115; /*stephalf*/
02939   else if (abs((int)(unmodsize - 1315l))<2)
02940     realsize = 1.31453414; /*stepihalf*/
02941   else if (abs((int)(unmodsize - 1577l))<2)
02942     realsize = 1.57744097; /*stepiihalf*/
02943   else if (abs((int)(unmodsize - 1893l))<2)
02944     realsize = 1.89292916; /*stepiiihalf*/
02945   else if (abs((int)(unmodsize - 2074l))<2)
02946     realsize = 2.0736;   /*stepiv*/
02947   else if (abs((int)(unmodsize - 2488l))<2)
02948     realsize = 2.48832;  /*stepv*/
02949   else if (abs((int)(unmodsize - 2986l))<2)
02950     realsize = 2.985984; /*stepvi*/
02951   /* the remaining magnification steps are represented with sufficient
02952      accuracy already */
02953   return(realsize);
02954 }
02955 
02956 
02957 /*-->DecodeArgs*/
02958 /*********************************************************************/
02959 /***************************** DecodeArgs ****************************/
02960 /*********************************************************************/
02961 void
02962 #if NeedFunctionPrototypes
02963 DecodeArgs(int argc, char *argv[])
02964 #else
02965 DecodeArgs(argc, argv)
02966 int     argc;
02967 char    *argv[];
02968 #endif
02969 {
02970   int     argind;            /* argument index for flags      */
02971   char    curarea[STRSIZE];  /* current file area             */
02972   char    curname[STRSIZE];  /* current file name             */
02973   char    *tcp, *tcp1;       /* temporary character pointers  */
02974   char    *this_arg;
02975   double  x_offset = 0.0, y_offset = 0.0;
02976 #ifdef __riscos
02977   int     ddi;
02978 #endif
02979 
02980 
02981 #ifndef KPATHSEA
02982   if ((tcp = getenv("TEXPXL")) != NULL) PXLpath = tcp;
02983 #ifdef LJ_RESIDENT_FONTS
02984   if ((tcp = getenv("TFMFONTS")) != NULL)
02985     TFMpath = tcp;
02986   else if ((tcp = getenv("TEXFONTS")) != NULL)
02987     TFMpath = tcp;
02988 #endif
02989 #endif
02990 
02991   if (argc == 2 && (strcmp (argv[1], "--version") == 0)) {
02992     extern KPSEDLL char *kpathsea_version_string;
02993     puts ("dvilj(k) 2.6");
02994     puts (kpathsea_version_string);
02995     puts ("Copyright (C) 1997 Gustaf Neumann.\n\
02996 There is NO warranty.  You may redistribute this software\n\
02997 under the terms of the GNU General Public License.\n\
02998 For more information about these matters, see the files\n\
02999 named COPYING and dvi2xx.c.\n\
03000 Primary author of Dvi2xx: Gustaf Neumann; -k maintainer: K. Berry.");
03001     exit (0); 
03002   }
03003 
03004 #ifdef LJ4
03005   /* check if last character is a 6 */
03006   LJ6 = ('6' == argv[0][strlen(argv[0])-1]);
03007 #endif
03008 
03009   argind = 1;
03010   while (argind < argc) {
03011     tcp = argv[argind];
03012     if (tcp[0] == '-' && tcp[1] != '\0') {
03013       ++tcp;
03014       switch (*tcp) {
03015 #ifndef KPATHSEA
03016       case 'a':       /* a selects different pxl font area */
03017         PXLpath = ++tcp;
03018         break;
03019 #endif
03020       case 'A':
03021         ManualFeed = _TRUE;
03022         break;
03023 #ifdef IBM3812
03024       case 'b':       /* first page from alternate casette */
03025         FirstAlternate = _TRUE;
03026         break;
03027 #endif
03028       case 'c':       /* number of copies to print */
03029         if ( sscanf(tcp + 1, "%hd", &ncopies) != 1 )
03030           Fatal("Argument of -c is not a valid integer\n");
03031         if (ncopies<1) {
03032           Warning("argument of -c < 1; set to 1!");
03033           ncopies = 1;
03034         }
03035         break;
03036 #ifdef DEBUG
03037       case '-':       /* --D selects Debug output */
03038         tcp++;
03039         if (*tcp == 'D') {
03040           Debug = _TRUE;
03041 #ifdef KPATHSEA
03042           sscanf(tcp + 1, "%u", &kpathsea_debug);
03043 #endif
03044           qfprintf(ERR_STREAM,"Debug output enabled\n");
03045         }
03046         break;
03047 #endif
03048 #ifdef LJ2P
03049       case 'd':       /* d selects DUPLEX mode  */
03050         tcp++;
03051         if (*tcp == '1' ) 
03052           DuplexMode = 1;
03053         else if (*tcp == '2') 
03054           DuplexMode = 2;
03055         else {
03056           Warning("Invalid DUPLEX mode, assuming DUPLEX=1, Long-Edge Binding");
03057           DuplexMode = 1;
03058         }
03059         break;
03060 #endif
03061       case 'D':       /* D selects DoublePage  */
03062         DoublePage = _TRUE;
03063         tcp++;
03064         if (*tcp == '1' || *tcp == '2') {
03065           if (*tcp == '2') 
03066             PrintFirstPart = _FALSE;
03067           else             
03068             PrintSecondPart = _FALSE;
03069           tcp++;
03070         }
03071         if (*tcp == '-') 
03072           PrintEmptyPages = _FALSE;
03073         break;
03074 #ifdef LJ4
03075       case 'E':       /* do not reset printer (go) */
03076         econoMode = _TRUE;
03077         break;
03078 #endif
03079       case 'e':       /* emit file is specified */
03080         EmitFileName = ++tcp;
03081 #ifdef MSDOS
03082         /* delete trailing ':' (causing hangup) */
03083         if (EmitFileName[strlen(EmitFileName)-1] == ':')
03084           EmitFileName[strlen(EmitFileName)-1] = '\0';
03085 #endif
03086 #ifdef OS2  /* repeated to avoid problems with stupid c preprocessors  */
03087         /* delete trailing ':' (causing hangup) */
03088         if (EmitFileName[strlen(EmitFileName)-1] == ':')
03089           EmitFileName[strlen(EmitFileName)-1] = '\0';
03090 #endif
03091         break;
03092       case 'f':       /* next arg is starting pagenumber */
03093         if ( sscanf(tcp + 1, "%ld", &FirstPage) != 1 )
03094           Fatal("Argument is not a valid integer\n");
03095         FirstPageSpecified = _TRUE;
03096         break;
03097 #ifdef LJ
03098       case 'g':       /* do not reset printer (go) */
03099         ResetPrinter = _FALSE;
03100         break;
03101 #endif
03102       case 'h':     /* copy header file through to output  */
03103         HeaderFileName = ++tcp;
03104         G_header = _TRUE;
03105         break;
03106 #if defined(LJ2P) || defined(IBM3812)
03107       case 'l':       /* landscape  */
03108         Landscape = _TRUE;
03109         break;
03110 #endif
03111 #ifdef MAKETEXPK
03112       case 'M':
03113         /* -M, -M1 => don't make font; -M0 => do.  */
03114         makeTexPK = *(tcp + 1) == '0';
03115 #ifdef KPATHSEA
03116         kpse_set_program_enabled (kpse_pk_format, MAKE_TEX_PK_BY_DEFAULT, kpse_src_cmdline);
03117 #endif /* KPATHSEA */
03118         break;
03119 #endif /* MAKETEXPK */
03120       case 'x':       /* specify x-offset */
03121         this_arg = 0;
03122         if (!(*++tcp)) {
03123           this_arg = (++argind >= argc ? 0 : argv[argind]);
03124         } else {
03125           this_arg = tcp;
03126         }
03127         if (!this_arg
03128             || sscanf(this_arg,"%lf", &x_offset) != 1)
03129           Fatal("Argument of -x is not a valid floating point number\n");
03130         break;
03131       case 'y':       /* specify y-offset */
03132         this_arg = 0;
03133         if (!(*++tcp)) {
03134           this_arg = (++argind >= argc ? 0 : argv[argind]);
03135         } else {
03136           this_arg = tcp;
03137         }
03138         if (!this_arg || sscanf(this_arg, "%lf", &y_offset) != 1)
03139           Fatal("Argument of -y is not a valid floating point number\n");
03140         break;
03141       case 'X':       /* specify X-origin in dots */
03142         this_arg = 0;
03143         if (!(*++tcp)) {
03144           this_arg = (++argind >= argc ? 0 : argv[argind]);
03145         } else {
03146           this_arg = tcp;
03147         }
03148         if (!this_arg || sscanf(this_arg,"%hd", &x_origin) != 1)
03149           Fatal("Argument of -X is not a valid integer\n");
03150         break;
03151       case 'Y':       /* specify Y-origin in dots */
03152         this_arg = 0;
03153         if (!(*++tcp)) {
03154           this_arg = (++argind >= argc ? 0 : argv[argind]);
03155         } else {
03156           this_arg = tcp;
03157         }
03158         if (!this_arg ||
03159             sscanf(this_arg, "%hd", &y_origin) != 1)
03160           Fatal("Argument of -Y is not a valid integer\n");
03161         break;
03162       case 'm':       /* specify magnification to use */
03163         switch ( (*++tcp) ) {
03164         case '#':
03165           /* next arg is a magnification to use */
03166           if ( sscanf(tcp + 1, "%ld", &usermag) != 1 )
03167             Fatal("Argument of mag is not a valid integer\n");
03168           break;
03169         case '0':
03170           usermag = 1000;
03171           break;
03172         case 'h':
03173         case 'H':
03174           usermag = 1095;
03175           break;
03176         case '1':
03177           usermag = 1200;
03178           break;
03179         case 'q':
03180           usermag = 1250;
03181           break;
03182         case '2':
03183           usermag = 1440;
03184           break;
03185         case '3':
03186           usermag = 1728;
03187           break;
03188         case '4':
03189           usermag = 2074;
03190           break;
03191         case '5':
03192           usermag = 2488;
03193           break;
03194         default:
03195           Fatal("%c is a bad mag step\n", *tcp);
03196         }
03197         break;
03198 #ifdef SUPERCOMMENT
03199       case 'o':     /* PostScript command to send */
03200         if ( ++argind >= argc )
03201           Fatal("No argument following -o\n", 0);
03202         PScmd[nps++] = argv[argind];
03203         break;
03204 #endif
03205       case 'p':       /* print n pages  */
03206         if ( sscanf(tcp + 1, "%ld", &PrintPages) != 1 )
03207           Fatal("Argument is not a valid integer\n");
03208         if (PrintPages < 1)
03209           Fatal("Argument of -p must be greater than 0\n");
03210         break;
03211       case 'q':       /* quiet operation */
03212         G_quiet = _TRUE;
03213         break;
03214       case 'r':       /* switch order to process pages */
03215         Reverse = (bool)(!Reverse);
03216         break;
03217 #ifdef LJ
03218       case 's':       /* specify X-origin in dots */
03219         this_arg = 0;
03220         if (!(*++tcp)) this_arg = (++argind >= argc ? 0 : argv[argind]);
03221         else           this_arg = tcp;
03222         if (!this_arg || sscanf(this_arg,"%hd", &pagesize) != 1)
03223           Fatal("Argument of -s is not a valid integer\n");
03224         /*
03225          * The original pgsiz_dots assumed  a resolution of 300dpi. This loses
03226          * at 600dpi so we must scale all.
03227          */
03228         switch (pagesize) {
03229         case 1: pgsiz_dots = 3150; break;         /* executive */
03230         case 2: pgsiz_dots = 3300; break;         /* letter */
03231         case 3: pgsiz_dots = 4200; break;         /* legal */
03232         case 26: pgsiz_dots = 3507; break;        /* a4 */
03233         case 80: pgsiz_dots = 2250; break;        /* monarc */
03234         case 81: pgsiz_dots = 2850; break;        /* com10 */
03235         case 90: pgsiz_dots = 2598; break;        /* int dl */
03236         case 91: pgsiz_dots = 2704; break;        /* int c5 */
03237         default: Fatal(
03238 #ifndef vms
03239                        "%hd is a bad value for pagesize (1,2,3,26,80,81,90,91)",
03240 #else
03241                        "%d is a bad value for pagesize (1,2,3,26,80,81,90,91)",
03242 #endif
03243                        pagesize);
03244         }
03245         break;
03246 #endif
03247       case 't':       /* ending pagenumber */
03248         if ( sscanf(tcp + 1, "%ld", &LastPage) != 1 )
03249           Fatal("Argument is not a valid integer\n");
03250         LastPageSpecified = _TRUE;
03251         break;
03252       case 'v':    /* verbatim mode (print pxl-file names) */
03253         G_verbose = _TRUE;
03254         break;
03255 
03256 #ifdef LJ
03257       case 'V':   /* bugfixes for various vendor's PCL emulations */
03258         tcp++;
03259         if (*tcp == 'K' || *tcp == 'k') 
03260           kyocera_mode = _TRUE;
03261         else
03262           if (*tcp == 'B' || *tcp == 'b') 
03263             brother_mode = _TRUE;
03264 # ifdef LJ4
03265        else
03266         if (*tcp == '6' || *tcp == '6') 
03267            LJ6 = _TRUE;
03268 # endif
03269         break;
03270 #endif
03271 
03272       case 'w':       /* don't print out warnings */
03273         G_nowarn = _TRUE;
03274         break;
03275 #ifdef LJ
03276       case 'z':
03277         PrintTestPage = (bool)(!PrintTestPage);
03278         break;
03279 #endif
03280 #ifdef LJ4
03281       case 'R':       /* number of copies to print */
03282         if ( sscanf(tcp + 1, "%d", &RESOLUTION) != 1 )
03283           Fatal("Argument of -R is not a valid integer\n");
03284         if (RESOLUTION != 300 && RESOLUTION != 600 ) {
03285           Warning("Resolution must be 300 or 600! Assuming 300.dpi.");
03286           RESOLUTION = 300;
03287         } else {
03288           if (RESOLUTION == 600) {
03289             MFMODE = MFMODE600;
03290             x_origin = 600;
03291             y_origin = 600;
03292           }
03293         }
03294         break;
03295       case 'W':  /* Set minimum width of compressed raster characters */
03296         CompressCharWidth = atoi(tcp+1);
03297         break;
03298       case 'C':  /* Set compression mode to use for raster characters */
03299         UseCompression = atoi(tcp+1);
03300         if ((UseCompression != 0) && (UseCompression != 2) && (UseCompression != 3))
03301           Fatal("Unsupported compression mode %d\n",UseCompression);
03302         break;
03303       case 'n': /* Download fonts raw */
03304         CompressFontMode = _FALSE;
03305         break;
03306 #endif
03307 #ifdef __riscos
03308       case 'i': /* name of directory to store diagrams in */
03309         tcp++; 
03310         ddi = 0;
03311         while (*tcp != ' ' && *tcp != '\0' && ddi < DIAGDIRSIZE-1) {
03312           diagdir[ddi++] = *tcp++;
03313         }
03314         diagdir[ddi] = '\0';
03315         break;
03316       case 'j': /* don't print digrams */
03317         printdiag = _FALSE;
03318         break;
03319       case 'k': /* cache diagram bitmap in document folder */
03320         cachediag = _TRUE;
03321         break;
03322       case 'P':
03323         RasterMultipass = 1;
03324         break;
03325 #endif
03326       default:
03327         fprintf(ERR_STREAM, "%c is not a valid flag\n", *tcp);
03328       }
03329     } else {
03330 
03331       (void) strcpy(filename, tcp);
03332       if (!strcmp(filename, "-")) {
03333         EmitFileName = "-";
03334 #ifdef RISC_USE_OSL
03335         dvifp = BINOPEN("Kbd:");
03336 #else
03337         dvifp = stdin;
03338        if (O_BINARY && !isatty(fileno(dvifp)))
03339          AssureBinary(fileno(dvifp));
03340 #endif
03341       } else {
03342 #ifdef KPATHSEA
03343         /* split into directory + file name */
03344        int tcplen, argvlen;
03345        tcp = (char *)xbasename(argv[argind]);/* this knows about any kind of slashes */
03346        tcplen = strlen(tcp);
03347        argvlen = strlen(argv[argind]);
03348        if (tcplen == argvlen)
03349          curarea[0] = '\0';
03350        else {
03351          (void) strcpy(curarea, argv[argind]);
03352          curarea[argvlen-tcplen] = '\0';
03353        }
03354 #else
03355         tcp = strrchr(argv[argind], '/');
03356         /* split into directory + file name */
03357         if (tcp == NULL) {
03358           curarea[0] = '\0';
03359           tcp = argv[argind];
03360         } else {
03361           (void) strcpy(curarea, argv[argind]);
03362           curarea[tcp-argv[argind]+1] = '\0';
03363           tcp += 1;
03364         }
03365 #endif
03366 
03367         (void) strcpy(curname, tcp);
03368         /* split into file name + extension */
03369         tcp1 = strrchr(tcp, '.');
03370         if (tcp1 == NULL) {
03371           (void) strcpy(rootname, curname);
03372           strcat(curname, ".dvi");
03373         } else {
03374           *tcp1 = '\0';
03375           (void) strcpy(rootname, curname);
03376           *tcp1 = '.';
03377         }
03378 
03379         (void) strcpy(filename, curarea);
03380         (void) strcat(filename, curname);
03381 
03382         if ((dvifp = BINOPEN(filename)) == FPNULL) {
03383           /* do not insist on .dvi */
03384           if (tcp1 == NULL) {
03385             int l = strlen(curname);
03386             if (l > 4)
03387               curname[l - 4] = '\0';
03388             l = strlen(filename);
03389             if (l > 4)
03390               filename[l - 4] = '\0';
03391           }
03392           if (tcp1 != NULL || (dvifp = BINOPEN(filename)) == FPNULL) {
03393 #ifdef MSC5
03394             Fatal("%s: can't find DVI file \"%s\"\n\n",
03395                   G_progname, filename);
03396 #else
03397             perror(filename);
03398             exit (EXIT_FAILURE);
03399 #endif
03400           }
03401         }
03402       } /* dvi filename != '-" */
03403     }
03404     argind++;
03405   }
03406 
03407 #ifdef LJ4
03408   pgsiz_dots *= (int)(RESOLUTION/300); /* rescale dots to page */
03409 #endif
03410   x_goffset = (short) MM_TO_PXL(x_offset) + x_origin;
03411   y_goffset = (short) MM_TO_PXL(y_offset) + y_origin;
03412 
03413   if (dvifp == FPNULL) {
03414     fprintf(ERR_STREAM,"\nThis is the DVI to %s converter version %s",
03415             PRINTER, VERSION);
03416 #ifdef SEVENBIT
03417     fprintf(ERR_STREAM,", 7bit");
03418 #endif
03419     fprintf(ERR_STREAM," (%s)\n", OS);
03420     fprintf(ERR_STREAM,"usage: %s [OPTION]... DVIFILE\n", G_progname);
03421 
03422     fprintf(ERR_STREAM,"OPTIONS are:\n");
03423 #ifdef DEBUG
03424     fprintf(ERR_STREAM,"\t--D ..... turns debug output on\n");
03425 #endif
03426 #ifndef KPATHSEA
03427     fprintf(ERR_STREAM,
03428             "\t-aX ..... X= searchpath leading to pixel-files (.pk or .pxl)\n");
03429 #endif
03430 #ifdef IBM3812
03431     fprintf(ERR_STREAM,
03432             "\t-b  ..... take paper for first page from alternate casette\n");
03433 #endif
03434     fprintf(ERR_STREAM,"\t-cX ..... X= number of copies\n");
03435 #ifdef LJ4
03436     fprintf(ERR_STREAM,"\t-CX ..... X= compression mode for raster chars; can be 0,2,3 (default=%d)\n", DEFAULT_COMPRESS_MODE);
03437 #endif
03438 #ifdef LJ2P
03439     fprintf(ERR_STREAM,"\t-dX ..... duplex, X=1: long-edge, 2: short-edge binding\n");
03440 #endif
03441     fprintf(ERR_STREAM,"\t-D  ..... turns doublepage output on; ");
03442     fprintf(ERR_STREAM,"-D1 odd pages only, -D2 even\n");
03443 #ifdef LJ4
03444     fprintf(ERR_STREAM,"\t-E  ..... print in econo-mode\n");
03445 #endif
03446     fprintf(ERR_STREAM,"\t-eX ..... X= output file\n");
03447     fprintf(ERR_STREAM,"\t-fX ..... print from begin of page number X\n");
03448 #ifdef LJ
03449     fprintf(ERR_STREAM,
03450             "\t-g  ..... do not reset printer at begin of job (go)\n");
03451 #endif
03452 #ifdef __riscos
03453     fprintf(ERR_STREAM,"\t-iX ..... X= name of dir to cache diagrams in\n");
03454     fprintf(ERR_STREAM,"\t-j  ..... don't print diagrams\n");
03455     fprintf(ERR_STREAM,"\t-k  ..... cache diagram bitmaps\n");
03456 #endif
03457     fprintf(ERR_STREAM,"\t-hX ..... X= name of headerfile\n");
03458 #ifdef LJ2P
03459     fprintf(ERR_STREAM,"\t-l  ..... landscape mode\n");
03460 #endif
03461 #ifdef MAKETEXPK
03462     fprintf(ERR_STREAM,"\t-MX ..... Don't generate missing PK files\n");
03463 #endif
03464     fprintf(ERR_STREAM,"\t-mX ..... magnification X=0;h;1;2;3;4;5;#xxxx\n");
03465 #ifdef LJ4
03466     fprintf(ERR_STREAM,"\t-n  ..... download fonts raw (default: compressed)\n");
03467 #endif
03468     fprintf(ERR_STREAM,"\t-pX ..... print X pages\n");
03469 #ifdef __riscos
03470     fprintf(ERR_STREAM,"\t-P  ..... Process printouts in 2 passes\n");
03471 #endif
03472     fprintf(ERR_STREAM,"\t-q  ..... quiet operation\n");
03473     fprintf(ERR_STREAM,"\t-r  ..... process pages in reverse order\n");
03474 #ifdef LJ4
03475     fprintf(ERR_STREAM,"\t-RX ..... set resolution to 300 or 600 dpi\n");
03476 #endif
03477 #ifdef LJ
03478     fprintf(ERR_STREAM,"\t-sX ..... set paper size to X (see documentation)\n");
03479 #endif
03480     fprintf(ERR_STREAM,"\t-tX ..... print to end of page number X\n");
03481     fprintf(ERR_STREAM,"\t-w  ..... don't print out warnings\n");
03482 #ifdef LJ4
03483     fprintf(ERR_STREAM,"\t-WX ..... X= minimum width of compressed chars (default=%d)\n",
03484             DEFAULT_COMPRESS_WIDTH);
03485 #endif
03486     fprintf(ERR_STREAM,"\t-v  ..... tell user which pixel-files are used\n");
03487 #ifdef LJ
03488     fprintf(ERR_STREAM,"\t-VX  .... Vendor options (kyocara or brother)\n");
03489 #endif
03490     fprintf(ERR_STREAM,"\t-xX ..... X= x-offset on printout in mm\n");
03491     fprintf(ERR_STREAM,"\t-yX ..... X= y-offset on printout in mm\n");
03492     fprintf(ERR_STREAM,"\t-XO ..... O= x page origin in dots (default=%d)\n",
03493             XDEFAULTOFF );
03494     fprintf(ERR_STREAM,"\t-YO ..... O= y page origin in dots (default=%d)\n",
03495             YDEFAULTOFF );
03496 #ifdef LJ
03497     fprintf(ERR_STREAM,"\t-z  ..... print test page with pagecounter after job\n");
03498 #endif
03499     fprintf(ERR_STREAM,"\t-   ..... dvifile is stdin (must be seekable); implies -e-\n");
03500 #ifdef KPATHSEA
03501     {
03502       extern KPSEDLL char *kpse_bug_address;
03503       putc ('\n', ERR_STREAM);
03504       fputs (kpse_bug_address, ERR_STREAM);
03505     }
03506 #endif
03507     exit(1);
03508   }
03509   if (EQ(EmitFileName, "")) {
03510     if ((EmitFileName = (char *)malloc( STRSIZE )) != NULL)
03511       allocated_storage += STRSIZE;
03512     else
03513       Fatal("Can't allocate storage of %d bytes\n",STRSIZE);
03514     (void) strcpy(EmitFileName, curname);
03515     if ((tcp1 = strrchr(EmitFileName, '.')))
03516       *tcp1 = '\0';
03517     strcat(EmitFileName, EMITFILE_EXTENSION);
03518   }
03519   if (G_quiet)
03520     G_verbose = _FALSE;
03521 }
03522 
03523 /*-->DoConv*/
03524 /*********************************************************************/
03525 /********************************  DoConv  ***************************/
03526 /*********************************************************************/
03527 long4
03528 #if NeedFunctionPrototypes
03529 DoConv(long4 num, long4 den, int convResolution)
03530 #else
03531 DoConv(num, den, convResolution)
03532 long4    num, den;
03533 int     convResolution;
03534 #endif
03535 {
03536   /*register*/ double conv;
03537   conv = ((double)num / (double)den) *
03538     ((double)mag / 1000.0) *
03539     ((double)convResolution/254000.0);
03540 
03541   return((long4)((1.0/conv)+0.5));
03542 }
03543 /*------------------------ end dviconv.c -------------------------------*/
03544 
03545 
03546 /*------------------------ begin dvimisc.c -----------------------------*/
03547 /*-->AllDone*/
03548 /**********************************************************************/
03549 /****************************** AllDone  ******************************/
03550 /**********************************************************************/
03551 #if NeedFunctionPrototypes
03552 void AllDone(bool PFlag)
03553 #else
03554 void AllDone(PFlag)
03555 bool PFlag;
03556 #endif
03557 {
03558 #ifdef TIMING
03559   double  time;
03560 #endif
03561 
03562   if (DoublePage && (PageParity==1)) { /* Shall we go around again?*/
03563     int k;
03564     char    n[STRSIZE];
03565 
03566     if (PrintEmptyPages && EvenPage && Reverse && PrintFirstPart) {
03567       WouldPrint ++;
03568       qfprintf(ERR_STREAM,"[EvenPage] ");
03569       FormFeed();
03570     }
03571 #ifdef LJ
03572     Reverse = (bool)!Reverse;
03573 #endif
03574     if (Reverse) {
03575       if (!PFlag) {
03576         FSEEK(dvifp, postambleptr, SEEK_SET);
03577         (void) NoSignExtend(dvifp, 1);
03578         ppagep = (long) NoSignExtend(dvifp, 4);
03579       }
03580       FSEEK(dvifp, ppagep, SEEK_SET);
03581     } else {
03582       FSEEK(dvifp,  14l, SEEK_SET);
03583       k = (int)NoSignExtend(dvifp, 1);
03584       GetBytes(dvifp, n, k);
03585     }
03586 
03587     if (PrintSecondPart) {
03588       if (PrintFirstPart) {
03589         qfprintf(ERR_STREAM,"\n----------------------starting second pass\n");
03590 #ifdef LJ
03591         EMIT1("\033&l2H"); /* Manual Feed */
03592 #endif
03593 #ifdef IBM3812
03594         PMPout(6,"\326\001\305\300\326\252");
03595         /* set display; ring bell; stop; clear display */
03596         PMPflush;
03597 #endif
03598       }
03599 
03600       if (PrintEmptyPages && Reverse) {
03601         if (ZeroPage) WouldPrint++;
03602         if ((WouldPrint%2) == 1) {
03603           qfprintf(ERR_STREAM,"[Padding] ");
03604           FormFeed();
03605         }
03606       }
03607       WouldPrint = 0;
03608       if (PrintEmptyPages && !Reverse && ZeroPage) {
03609         WouldPrint++;
03610         qfprintf(ERR_STREAM,"[ZeroPage] ");
03611         FormFeed();
03612       }
03613       PageParity = 0;
03614       PrintPages = StartPrintPages;
03615       return;
03616     }
03617   }
03618 
03619   if (EvenPage && DoublePage && !Reverse) WouldPrint++;
03620 
03621   if (PrintEmptyPages && DoublePage && PrintSecondPart) {
03622     if (Reverse) {
03623       if (ZeroPage) {
03624         WouldPrint ++;
03625         qfprintf(ERR_STREAM,"[ZeroPage] ");
03626         FormFeed();
03627       }
03628     }
03629     else if ((WouldPrint%2) != 0) {
03630       qfprintf(ERR_STREAM,"[Padding] ");
03631       FormFeed();
03632     }
03633   }
03634 
03635 #ifdef IBM3812
03636   PMPout(10, "\373\010PMP.init");  /* re-init printer  */
03637   PMPflush;
03638 
03639   if (used_fontstorage > MAXFONTSTORAGE) {
03640     Warning("\n\7used font_storage of %s: %ld Bytes (of %ld)\7",
03641             PRINTER, (long)used_fontstorage, MAXFONTSTORAGE);
03642     Warning("Try to format file in separate runs!");
03643   } else
03644     qfprintf(ERR_STREAM,"\nAll done, used font_storage of %s: %ld Bytes (of %ld)",
03645               PRINTER, (long)used_fontstorage, MAXFONTSTORAGE);
03646 #endif
03647 #ifdef LJ
03648 # ifdef SHARP_JX_9500
03649   if (used_fontstorage > MAXFONTSTORAGE) {
03650     Warning("\n\7used font_storage of %s: %ld Bytes (of %ld)\7",
03651             PRINTER, (long)used_fontstorage, MAXFONTSTORAGE);
03652     Warning("Try to format file in separate runs!");
03653   } else
03654     qfprintf(ERR_STREAM,"\nAll done, used font_storage of %s: %ld Bytes (of %ld)",
03655               PRINTER, (long)used_fontstorage, MAXFONTSTORAGE);
03656 # else
03657   qfprintf(ERR_STREAM,"\nAll done, used font_storage of %s: %ld Bytes",
03658             PRINTER, (long)used_fontstorage);
03659 # endif
03660 #ifdef LJ_RESIDENT_FONTS
03661   qfprintf(ERR_STREAM," + %d resident font%s", resident_count,
03662            resident_count == 1 ? "" : "s");
03663 #endif
03664   EMIT1("\033E");
03665 #ifdef LJ4
03666   EMIT1("\033%%-12345X");   /* what does it? */
03667 #endif
03668   if (PrintTestPage) EMIT1("\033z");
03669 #ifdef vms
03670   /* last record is not flushed to file, unless it is completely filled */
03671   for (kk = (int)((*outfp)->_cnt); kk > 0; --kk) 
03672     putc('\0',outfp);
03673   fflush(outfp);
03674 #endif
03675 #endif
03676 
03677   if (!G_quiet) {
03678     fprintf(ERR_STREAM,"\nDynamically allocated storage: %ld Bytes \n",
03679             (long)allocated_storage);
03680     fprintf(ERR_STREAM,"%d characters downloaded as soft fonts\n", G_ncdl);
03681 
03682 #ifdef TIMING
03683 #ifdef BSD_TIME_CALLS
03684     ftime(&timebuffer);
03685     time = (timebuffer.time + (float)(timebuffer.millitm)/1000.0) - start_time;
03686 #else
03687     gettimeofday(&Tp, NULL);
03688     time = (Tp.tv_sec + (float)(Tp.tv_usec)/1000000.0) - start_time;
03689 #endif
03690 
03691     if (ndone > 0) {
03692       fprintf(ERR_STREAM,
03693               "Time of complete run: %.2f seconds, %d page(s), %.2f seconds/page",
03694               time, ndone, time / ndone);
03695       fprintf(ERR_STREAM," (%.2f ppm)\n",(ndone * 60) / time);
03696     }
03697     fprintf(ERR_STREAM,"\n");
03698 #endif
03699   }
03700   CloseFiles();
03701   exit(G_errenc);
03702 }
03703 
03704 /*-->DoSpecial*/
03705 /*********************************************************************/
03706 /*****************************  DoSpecial  ***************************/
03707 /*********************************************************************/
03708 
03709 #define PSFILE 0
03710 #define ORIENTATION 1
03711 #define RESETPOINTS 2
03712 #define DEFPOINT 3
03713 #define FILL 4
03714 #define GRAY 5
03715 #define PATTERN 6
03716 #define HPFILE 7
03717 #define LLX 8
03718 #define LLY 9
03719 #define URX 10
03720 #define URY 11
03721 #define RWI 12
03722 #define RHI 13
03723 
03724 
03725 KeyDesc KeyTab[] = {
03726   { "psfile", String },
03727   { "orientation", Integer},
03728   { "resetpoints", String},
03729   { "defpoint", String},
03730   { "fill", String},
03731   { "gray", Integer},
03732   { "pattern", Integer},
03733   { "hpfile", String},
03734   { "llx", Integer},
03735   { "lly", Integer},
03736   { "urx", Integer},
03737   { "ury", Integer},
03738   { "rwi", Integer},
03739   { "rhi", Integer}
03740   /*,
03741     {"hsize", Dimension},
03742     {"vsize", Dimension},
03743     {"hoffset", Dimension},
03744     {"voffset", Dimension},
03745     {"hscale", Number},
03746     {"vscale", Number}*/
03747 };
03748 
03749 #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
03750 
03751 #ifdef __riscos
03752 # ifdef LJ
03753 
03754 /* Compare two strings, ignoring case;
03755    s1 pointer to null-terminated keyword, s2 pointer to parseline;
03756    returns (if successful) pointer to character following keyword in s2 */
03757 #if NeedFunctionPrototypes
03758 bool StrCompare(char *s1, char *s2, char **end)
03759 #else
03760 bool StrCompare(s1, s2, end)
03761 char *s1;
03762 char *s2;
03763 char **end;
03764 #endif
03765 {
03766   char *a,*b;
03767   
03768   a = s1; 
03769   b = s2;
03770   while (*a != '\0') {
03771     if (tolower(*a) != tolower(*b)) return(_FALSE);
03772     a++; 
03773     b++;
03774   }
03775   *end = b; 
03776   return(_TRUE);
03777 }
03778 
03779 /* Read <number> integer values from string and store results in
03780    <result>. Returns number + of arguments actually read, end =
03781    pointer to char following last number */
03782 #if NeedFunctionPrototypes
03783 int ParseNumbers(char *str, int *result, int number, char **end)
03784 #else
03785 int ParseNumbers(str, result, number, end)
03786 char *str;
03787 int *result;
03788 int number;
03789 char **end;
03790 #endif
03791 {
03792   char *s;
03793   int count = 0;
03794   
03795   s = str;
03796   while ((*s != '\0') && (count < number)) {
03797     while ((*s == ' ') || (*s == ',') || (*s == '=')) 
03798       s++;
03799     if (*s != '\0') {
03800       result[count++] = strtod(s,&s);
03801     }
03802   }
03803   while ((*s == ' ') || (*s == ',') || (*s == '=')) 
03804     s++;
03805   *end = s; 
03806   return(count);
03807 }
03808 
03809 
03810 /* Diagram commands are parsed separately since the format varies from the one
03811 +    used by the other special commands */
03812 #if NeedFunctionPrototypes
03813 bool ParseDiagram(char *str)
03814 #else
03815 bool ParseDiagram(str)
03816 char *str;
03817 #endif
03818 {
03819   diagtrafo dt;
03820   char *s,*sh;
03821   char diagname[STRSIZE];
03822   int results[4],no;
03823 
03824   s = str;
03825   while (*s == ' ') 
03826     s++;
03827   if ((StrCompare("drawfile",s,&s)) || (StrCompare("DVIview_diagram",s,&s))) {
03828 
03829     if (printdiag == _FALSE) 
03830       return(_TRUE); /* it's a diagram, but don't print */
03831 
03832     while ((*s == ' ') || (*s == '=')) 
03833       s++; /* space or '=' separates keyword/keyval */
03834 
03835     if (*s == '\0') {
03836       fprintf(ERR_STREAM,"No filename given for \\special-diagram!\n"); 
03837       return(_TRUE);
03838     }
03839     sh = diagname;
03840     while ((*s != ' ') && (*s != ',') && (*s != '\0')) 
03841       *sh++ = *s++;
03842     *sh = '\0';
03843 
03844     /* Set up default values */
03845     dt.scalex = dt.scaley = 100;
03846     dt.cropl = dt.cropb = dt.cropr = dt.cropt = 0;
03847     while (*s != '\0') {
03848       while ((*s == ' ') || (*s == ',')) 
03849         s++;
03850       if (*s != '\0') {
03851         if (StrCompare("scale",s,&s)) {
03852           if ((no = ParseNumbers(s,results,2,&s)) != 2) {
03853             fprintf(ERR_STREAM,
03854                    "Too few arguments (%d) given for <scale> - ignored.\n",no);
03855           }
03856           dt.scalex = results[0]; 
03857           dt.scaley = results[1];
03858         }
03859         else if (StrCompare("crop",s,&s)) {
03860           if ((no = ParseNumbers(s,results,4,&s)) != 4) {
03861             fprintf(ERR_STREAM,
03862                    "Too few arguments (%d) given for <crop> - ignored.\n",no);
03863           }
03864           dt.cropl = results[0]; 
03865           dt.cropr = results[1];
03866           dt.cropt = results[2]; 
03867           dt.cropb = results[3];
03868         }
03869         else {
03870           fprintf(ERR_STREAM,"Bad \\special keyword - <%s> ignored\n",s);
03871           /* skip over this word */
03872           while ((*s != ' ') && (*s != ',') && (*s != '=') && (*s != '\0')) 
03873             s++;
03874         }
03875       }
03876     }
03877     /* fprintf(ERR_STREAM,"Diagram: %s, scale %d %d, crop %d %d %d %d\n",
03878        diagname,dt.scalex,dt.scaley,dt.cropl,dt.cropb,dt.cropr,dt.cropt);*/
03879     diagram(diagname,&dt);
03880     return(_TRUE);
03881   }
03882   else 
03883     return(_FALSE);
03884 }
03885 # endif /* LJ */
03886 #endif /* __riscos */
03887 
03888 
03889 /* interpret a \special command, made up of keyword=value pairs */
03890 #if NeedFunctionPrototypes
03891 void DoSpecial(char *str, int n)
03892 #else
03893 void DoSpecial(str, n)
03894 char *str;
03895 int  n;
03896 #endif
03897 {
03898   char    spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE];
03899   char    *sf = NULL, *psfile = NULL;
03900   float   x,y;
03901   long4   x_pos, y_pos;
03902   KeyWord k;
03903   int     i, j, j1;
03904   static  int   GrayScale = 10, Pattern = 1;
03905   static  bool  GrayFill = _TRUE;
03906   static  long4 p_x[80], p_y[80];
03907   int llx=0, lly=0, urx=0, ury=0, rwi=0, rhi=0;
03908 #ifdef WIN32
03909   char    *gs_path;
03910 #endif
03911 
03912   str[n] = '\0';
03913   spbuf[0] = '\0';
03914 
03915   SetPosn(h, v);
03916 #ifdef __riscos
03917 #ifdef LJ
03918   if (ParseDiagram(str)) 
03919     return;
03920 #endif
03921 #endif
03922  
03923   while ( (str = GetKeyStr(str, &k)) != NULL ) {
03924     /* get all keyword-value pairs */
03925     /* for compatibility, single words are taken as file names */
03926     if ( k.vt == None && access(k.Key, 0) == 0) {
03927       if ( sf
03928 #ifdef KPATHSEA
03929            && !kpse_tex_hush ("special")
03930 #endif
03931          )
03932         Warning("More than one \\special file name given. %s ignored", sf);
03933       (void) strcpy(spbuf, k.Key);
03934       sf = spbuf;
03935       /*
03936         for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
03937         */
03938     } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 )
03939       switch (i) {
03940       case PSFILE:
03941         if (sf
03942 #ifdef KPATHSEA
03943             && !kpse_tex_hush ("special")
03944 #endif
03945             )
03946             Warning("More than one \\special file name given. %s ignored", sf);
03947         (void) strcpy(spbuf, k.Val);
03948         psfile = spbuf;
03949         /*
03950           for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
03951           */
03952         break;
03953         
03954       case HPFILE:
03955         if (sf)
03956             Warning("More than one \\special file name given. %s ignored", sf);
03957         (void) strcpy(spbuf, k.Val);
03958         sf = spbuf;
03959         /*
03960           for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
03961           */
03962         break;
03963 
03964       case ORIENTATION:
03965 #ifdef IBM3812
03966         if ((k.v.i >= 0) && (k.v.i < 4)) {
03967           last_ry = UNKNOWN;
03968           sprintf(PMPformat, "\322%c", (unsigned char)k.v.i);
03969           PMPout(2, PMPformat);
03970           if (k.v.i == 1) Landscape = _TRUE;
03971           else if (k.v.i == 0) Landscape = _FALSE;
03972         }
03973 #endif
03974 #ifdef LJ
03975         if ((k.v.i >= 0) && (k.v.i < 2)) {
03976           last_rx = last_ry = UNKNOWN;
03977           EMIT2("\033&l%dO\033*rF", (unsigned char)k.v.i);
03978         }
03979 #endif
03980         else
03981 #ifdef KPATHSEA
03982            if (!kpse_tex_hush ("special"))
03983 #endif
03984           Warning( "Invalid orientation (%d)given; ignored.", k.v.i);
03985         break;
03986 
03987       case RESETPOINTS:
03988         (void) strcpy(spbuf, k.Val);
03989 
03990         sf = NULL;
03991         break;
03992 
03993       case DEFPOINT:
03994         (void) strcpy(spbuf, k.Val);
03995         i = sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys);
03996         if (i>0) {
03997           x_pos = h; 
03998           y_pos = v;
03999           if (i>1) {
04000             if (sscanf(xs,"%fpt",&x)>0) {
04001               fprintf(ERR_STREAM,"x = %f\n",x);
04002               x_pos = PT_TO_DVI(x);
04003             }
04004           }
04005           if (i>2) {
04006             if (sscanf(ys,"%fpt",&y)>0) {
04007               fprintf(ERR_STREAM,"y = %f\n",y);
04008               y_pos = PT_TO_DVI(y);
04009             }
04010           }
04011           p_x[j]=x_pos;
04012           p_y[j]=y_pos;
04013         } else
04014 #ifdef KPATHSEA
04015               if (!kpse_tex_hush ("special"))
04016 #endif
04017           Warning("invalid point definition\n");
04018 
04019         sf = NULL;
04020         break;
04021 
04022       case FILL:
04023         (void) strcpy(spbuf, k.Val);
04024         i = sscanf(spbuf,"%d/%d %s",&j,&j1,xs);
04025         if (i>1) {
04026 #ifdef LJ
04027           SetPosn(p_x[j], p_y[j]);
04028           x_pos = (long4)PIXROUND(p_x[j1]-p_x[j], hconv);
04029           y_pos = (long4)PIXROUND(p_y[j1]-p_y[j], vconv);
04030           if (labs(x_pos)<labs(y_pos)) x_pos = x_pos+3;
04031           else                         y_pos = y_pos+3;
04032           if (GrayFill) {
04033             EMIT4("\033*c%lda%ldb%dg2P", x_pos, y_pos, GrayScale);
04034           } else {
04035             EMIT4("\033*c%lda%ldb%dg3P", x_pos, y_pos, Pattern);
04036           }
04037           last_rx = last_ry = UNKNOWN;
04038 #endif
04039         }
04040         break;
04041 
04042       case GRAY:
04043         if ((k.v.i >= 0) && (k.v.i < 101)) {
04044           GrayScale = k.v.i;
04045           GrayFill = _TRUE;
04046         } else
04047 #ifdef KPATHSEA
04048            if (!kpse_tex_hush ("special"))
04049 #endif
04050           Warning( "Invalid gray scale (%d) given; ignored.", k.v.i);
04051         break;
04052 
04053       case PATTERN:
04054         if ((k.v.i >= 0) && (k.v.i < 7)) {
04055           Pattern = k.v.i;
04056           GrayFill = _FALSE;
04057         } else
04058 #ifdef KPATHSEA
04059            if (!kpse_tex_hush ("special"))
04060 #endif
04061           Warning( "Invalid pattern (%d) given; ignored.", k.v.i);
04062         break;
04063 
04064       case LLX: llx = k.v.i; break;
04065       case LLY: lly = k.v.i; break;
04066       case URX: urx = k.v.i; break;
04067       case URY: ury = k.v.i; break;
04068       case RWI: rwi = k.v.i; break;
04069       case RHI: rhi = k.v.i; break;
04070 
04071       default:
04072 #ifdef KPATHSEA
04073            if (!kpse_tex_hush ("special"))
04074 #endif
04075         Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val);
04076         break;
04077       }
04078       
04079     else
04080 #ifdef KPATHSEA
04081            if (!kpse_tex_hush ("special"))
04082 #endif
04083       Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key);
04084   }
04085 
04086   if ( sf || psfile ) {
04087     last_rx = last_ry = UNKNOWN;
04088 #ifdef IBM3812
04089     PMPflush;
04090 #endif
04091     if (sf) {
04092       if (i == HPFILE) 
04093         CopyHPFile( sf );
04094       else 
04095         CopyFile( sf );
04096     }
04097     else
04098 #ifdef LJ
04099       if (psfile) {
04100         /* int height = rwi * (urx - llx) / (ury - lly);*/
04101         int width  = urx - llx;
04102         int height = ury - lly;
04103         char cmd[255];
04104         int scale_factor    = 3000 * width / rwi;
04105         int adjusted_height = height * 300/scale_factor;
04106         int adjusted_llx    = llx    * 300/scale_factor;
04107         char *printer = "ljetplus"; /* use the most stupid one */
04108 
04109 
04110         char scale_file_name[255];
04111         char *scale_file = tmpnam(scale_file_name);
04112         char *pcl_file = tmpnam(NULL);  
04113         FILEPTR scalef;
04114 
04115         if ( (scalef = BOUTOPEN(scale_file)) == FPNULL ) {
04116           Warning("Unable to open file %s for writing", scale_file );
04117           return;
04118         }
04119         fprintf(scalef, "%.2f %.2f scale\n%d %d translate\n",  
04120                 300.0/scale_factor, 300.0/scale_factor,
04121                 0, adjusted_height == height ? 0 : ury);
04122         BCLOSE( scalef );
04123 
04124 #ifdef WIN32
04125        gs_path = getenv("GS_PATH");
04126        if (!gs_path)
04127          gs_path = "gswin32c.exe";
04128         sprintf(cmd,"%s -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit",
04129               gs_path, printer, pcl_file, scale_file, psfile);
04130 #else
04131         sprintf(cmd,"gs -q -dSIMPLE -dSAFER -dNOPAUSE -sDEVICE=%s -sOutputFile=%s %s %s showpage.ps -c quit",
04132                 printer, pcl_file, scale_file, psfile);
04133 #endif
04134 #ifdef DEBUGGS   
04135         fprintf(stderr,
04136           "PS-file '%s' w=%d, h=%d, urx=%d, ury=%d, llx=%d, lly=%d, rwi=%d\n",
04137                 psfile, urx - llx, height, urx,ury,llx,lly, rwi);
04138         fprintf(stderr,"%s\n",cmd);
04139 #endif
04140         if (system(cmd)) {
04141           Warning("execution of '%s' returned an error", cmd);
04142         } else {
04143 #ifdef DEBUGGS   
04144           fprintf(stderr, "o=%d, h=%d, so=%d, sh=%d\n", 
04145                   llx, height, adjusted_llx, adjusted_height);
04146           
04147           fprintf(stderr, "OLD x=%d, y=%d\n", 
04148                   (int)PIXROUND(h, hconv) + x_goffset,
04149                   (int)PIXROUND(v, vconv) + y_goffset);
04150 #endif  
04151           v -= 65536l*adjusted_height; 
04152           h -= 65536l*adjusted_llx; /* *300/scale_factor;*/
04153           SetPosn(h, v);
04154 #ifdef DEBUGGS   
04155           fprintf(stderr, "NEW x=%d, y=%d\n", 
04156                   (int)PIXROUND(h, hconv) + x_goffset,
04157                   (int)PIXROUND(v, vconv) + y_goffset);
04158 #endif
04159 
04160           CopyHPFile( pcl_file );
04161           /* unlink(pcl_file); */
04162           /* unlink(scale_file); */
04163         }
04164       }
04165 #endif /* LJ */
04166   }
04167 }
04168 
04169 
04170 
04171 
04172 /*-->GetKeyStr*/
04173 /**********************************************************************/
04174 /*****************************  GetKeyStr  ****************************/
04175 /**********************************************************************/
04176 /* extract first keyword-value pair from string (value part may be null)
04177  * return pointer to remainder of string
04178  * return NULL if none found
04179  */
04180 char    KeyStr[STRSIZE];
04181 char    ValStr[STRSIZE];
04182 #if NeedFunctionPrototypes
04183 char *GetKeyStr(char *str, KeyWord *kw )
04184 #else
04185 char    *GetKeyStr( str, kw )
04186 char    *str;
04187 KeyWord *kw;
04188 #endif
04189 {
04190   char    *s, *k, *v, t;
04191   if ( !str )
04192     return( NULL );
04193   for (s = str; *s == ' '; s++)
04194     ;          /* skip over blanks */
04195   if (*s == '\0')
04196     return( NULL );
04197   for (k = KeyStr; /* extract keyword portion */
04198        *s != ' ' && *s != '\0' && *s != '=';
04199        *k++ = *s++)
04200     ;
04201   *k = '\0';
04202   kw->Key = KeyStr;
04203   kw->Val = v = NULL;
04204   kw->vt = None;
04205   for ( ; *s == ' '; s++)
04206     ;            /* skip over blanks */
04207   if ( *s != '=' )         /* look for "=" */
04208     return( s );
04209   for (s++; *s == ' '; s++);      /* skip over blanks */
04210   if ( *s == '\'' || *s == '\"' )  /* get string delimiter */
04211     t = *s++;
04212   else
04213     t = ' ';
04214   for (v = ValStr; /* copy value portion up to delim */
04215        *s != t && *s != '\0';
04216        *v++ = *s++)
04217     ;
04218   if ( t != ' ' && *s == t )
04219     s++;
04220   *v = '\0';
04221   kw->Val = ValStr;
04222   kw->vt = String;
04223   return( s );
04224 }
04225 
04226 
04227 /*-->GetKeyVal*/
04228 /**********************************************************************/
04229 /*****************************  GetKeyVal  ****************************/
04230 /**********************************************************************/
04231 /* get next keyword-value pair decode value according to table entry  */
04232 #if NeedFunctionPrototypes
04233 bool GetKeyVal(KeyWord *kw, KeyDesc tab[], int nt, int *tno)
04234 #else
04235 bool    GetKeyVal( kw, tab, nt, tno)
04236 KeyWord *kw;
04237 KeyDesc tab[];
04238 int     nt;
04239 int     *tno;
04240 #endif
04241 {
04242   int     i;
04243   char    c = '\0';
04244   *tno = -1;
04245   for (i = 0; i < nt; i++)
04246     if ( IsSame(kw->Key, tab[i].Entry) ) {
04247       *tno = i;
04248       switch ( tab[i].Typ ) {
04249       case None:
04250         if ( kw->vt != None )
04251           return( _FALSE );
04252         break;
04253       case String:
04254         if ( kw->vt != String )
04255           return( _FALSE );
04256         break;
04257       case Integer:
04258         if ( kw->vt != String )
04259           return( _FALSE );
04260         if ( sscanf(kw->Val, "%d%c", &(kw->v.i), &c) != 1 || c != '\0' )
04261           return( _FALSE );
04262         break;
04263       }
04264       kw->vt = tab[i].Typ;
04265       return( _TRUE );
04266     }
04267   return( _TRUE );
04268 }
04269 
04270 
04271 /*-->IsSame*/
04272 /**********************************************************************/
04273 /*******************************  IsSame  *****************************/
04274 /**********************************************************************/
04275 /* compare strings, ignore case */
04276 #if NeedFunctionPrototypes
04277 bool IsSame(char *a, char *b)
04278 #else
04279 bool IsSame(a, b)
04280 char    *a, *b;
04281 #endif
04282 {
04283   char *x, *y;
04284   
04285   for (x = a, y = b; *a; a++, b++)
04286     if ( tolower(*a) != tolower(*b) )
04287       return( _FALSE );
04288 
04289   return( *a == *b ? _TRUE : _FALSE );
04290 }
04291 
04292 
04293 /*-->FindPostAmblePtr*/
04294 /**********************************************************************/
04295 /************************  FindPostAmblePtr  **************************/
04296 /**********************************************************************/
04297 /* this routine will move to the end of the file and find the start
04298     of the postamble */
04299 #if NeedFunctionPrototypes
04300 void FindPostAmblePtr(long *postambleptr)
04301 #else
04302 void FindPostAmblePtr(postambleptr)
04303 long *postambleptr;
04304 #endif
04305 {
04306   long4    i;
04307   FSEEK(dvifp,  0l, SEEK_END);   /* goto end of file */
04308   *postambleptr = FTELL(dvifp) - 4;
04309   FSEEK(dvifp, *postambleptr, SEEK_SET);
04310   while (_TRUE) {
04311     FSEEK(dvifp, --(*postambleptr), SEEK_SET);
04312     if (((i = NoSignExtend(dvifp, 1)) != 223) &&
04313         (i != DVIFORMAT))
04314       Fatal("Bad end of DVI file");
04315     if (i == DVIFORMAT)
04316       break;
04317   }
04318   FSEEK(dvifp, (*postambleptr) - 4, SEEK_SET);
04319   (*postambleptr) = NoSignExtend(dvifp, 4);
04320   FSEEK(dvifp, *postambleptr, SEEK_SET);
04321 }
04322 
04323 
04324 /*-->ReadPostAmble*/
04325 /**********************************************************************/
04326 /**************************  ReadPostAmble  ***************************/
04327 /**********************************************************************/
04328 /***********************************************************************
04329     This routine is used to read in the postamble values.  It
04330     initializes the magnification and checks the stack height prior to
04331     starting printing the document.
04332 ***********************************************************************/
04333 #if NeedFunctionPrototypes
04334 void ReadPostAmble(bool load)
04335 #else
04336 void ReadPostAmble(load)
04337 bool load;
04338 #endif
04339 {
04340   FindPostAmblePtr(&postambleptr);
04341   if (NoSignExtend(dvifp, 1) != POST)
04342     Fatal("POST missing at head of postamble");
04343 #ifdef DEBUG
04344   if (Debug)
04345     fprintf(ERR_STREAM,"got POST command\n");
04346 #endif
04347   ppagep = (long)NoSignExtend(dvifp, 4);
04348   num = NoSignExtend(dvifp, 4);
04349   den = NoSignExtend(dvifp, 4);
04350   mag = NoSignExtend(dvifp, 4);
04351   if ( usermag > 0 && usermag != mag )
04352     Warning("DVI magnification of %ld over-ridden by user (%ld)",
04353             (long)mag, usermag );
04354   if ( usermag > 0 )
04355     mag = usermag;
04356   hconv = DoConv(num, den, hconvRESOLUTION);
04357   vconv = DoConv(num, den, vconvRESOLUTION);
04358   (void) NoSignExtend(dvifp, 4);   /* height-plus-depth of tallest page */
04359   (void) NoSignExtend(dvifp, 4);   /* width of widest page */
04360   if (NoSignExtend(dvifp, 2) >= STACK_SIZE)
04361     Fatal("Stack size is too small");
04362   (void) NoSignExtend(dvifp, 2);   /* this reads the number of pages in */
04363   /* the DVI file */
04364 #ifdef DEBUG
04365   if (Debug)
04366     fprintf(ERR_STREAM,"now reading font defs");
04367 #endif
04368   if (load)
04369     GetFontDef();
04370 }
04371 
04372 #ifdef IBM3812
04373 /*-->PMPLine*/
04374 /**********************************************************************/
04375 /*****************************  PMPLine  ******************************/
04376 /**********************************************************************/
04377 /* drawing lines on the 3812 using PMP vector commands */
04378 #if NeedFunctionPrototypes
04379 void PMPLine(int w, int y, int x)
04380 #else
04381 void PMPLine(w, y, x)
04382 int     w, y, x;
04383 #endif
04384 {
04385 
04386   if ((w == 0) || (x == 0 && y == 0))
04387     return;
04388 
04389   /*
04390     fprintf(ERR_STREAM,"w=%d / %d - %d, y=%d / %d - %d, x=%d / %d - %d\n",
04391     w,(char)(w & 0xff),(int)((signed_char)(w & 0xff)),
04392     y,(char)(y & 0xff),(int)((signed_char)(y & 0xff)),
04393     x,(char)(x & 0xff),(int)((signed_char)(x & 0xff)));
04394     */
04395 
04396   if ( (((signed_char)(x & 0xff)) == x ) &&
04397        ( ((signed_char)(y & 0xff)) == y ) ) {
04398     PMPcont(6);
04399     PMPout(1, "\370");
04400     EMITWORD(3);      /* length of vector */
04401     PMPoutC((unsigned char)(0x80 | 0x00 | (unsigned char) w));
04402     PMPoutC((signed_char)(y & 0xff));
04403     PMPoutC((signed_char)(x & 0xff));
04404     /*
04405       fprintf(ERR_STREAM,"F8 00 03: w=%d, x=%d(%d-%.2X), y=%d(%d-%.2X),\n",
04406       w,x,(char)(x & 0xff),(signed_char)(x & 0xff),
04407       y,(char)(y & 0xff),(signed_char)(y & 0xff));
04408       */
04409 
04410   } else {
04411     PMPcont(8);
04412     PMPout(1, "\370");
04413     EMITWORD(4 + 1);      /* length of vector */
04414     PMPoutC((unsigned char)(0xC0 | 0x00 | (unsigned char) w));
04415     EMITWORD(y);
04416     EMITWORD(x);
04417     /*
04418       fprintf(ERR_STREAM,"F8 00 05: w=%d, x=%d, y=%d,\n", w,x,y);
04419       */
04420   }
04421 }
04422 
04423 
04424 #endif
04425 /*-->SetRule*/
04426 /**********************************************************************/
04427 /*****************************  SetRule  ******************************/
04428 /**********************************************************************/
04429 /*   this routine will draw a rule */
04430 #if NeedFunctionPrototypes
04431 void SetRule(long4 a, long4 b, int Set)
04432 #else
04433 void SetRule(a, b, Set)
04434 long4    a, b;
04435 int     Set;
04436 #endif
04437 {
04438   long4    xx, yy;
04439 #ifdef IBM3812
04440   short   hor_offset, vert_offset, ll;
04441 #endif
04442   if ( a > 0 && b > 0 ) {
04443     SetPosn(h, v);             /* lower left corner */
04444     xx = (long4)PIXROUND(b, hconv);     /* width */
04445     yy = (long4)PIXROUND(a, vconv);     /* height */
04446 
04447 #ifdef DEBUG
04448     if (Debug)
04449       fprintf(ERR_STREAM,"Rule xx=%ld, yy=%ld\n", (long)xx, (long)yy);
04450 #endif
04451 
04452 #ifdef IBM3812
04453     hor_offset  = (short)(last_ry - yy);
04454     if (hor_offset < 0) yy += hor_offset;
04455     if (last_rx < 0) xx += last_rx;
04456 
04457     if (Landscape) {
04458       if (last_ry > MAX_PAGE_WIDTH) yy += MAX_PAGE_WIDTH-last_ry;
04459       hor_offset  = (short)(MAX_PAGE_HEIGHT - (last_rx + xx));
04460     } else {
04461       if (last_ry > MAX_PAGE_HEIGHT) yy += MAX_PAGE_HEIGHT-last_ry;
04462       hor_offset  = (short)(MAX_PAGE_WIDTH - (last_rx + xx));
04463     }
04464     if (hor_offset < 0) xx += hor_offset;
04465 
04466     if ((xx > 31) && (yy > 31)) {
04467       /*
04468        *   fill area by multiple lines  (kind of a mess)
04469        *   process for simplicity always horizontally
04470        */
04471 
04472       /* 
04473          fprintf(ERR_STREAM,"large box: w=%d,x=%d,y=%d\n",(int)yy,(int)xx,0);
04474          */
04475       
04476       hor_offset  = HOR_HALF(30);
04477       MoveHor(hor_offset);
04478       vert_offset = VERT_HALF(30);
04479       MoveVert(-vert_offset);
04480       ll = (short)xx - 30;
04481 
04482       for (; yy > 30; yy -= 30) {
04483         PMPLine(30, 0, ll);
04484         MoveHor(-ll);
04485         MoveVert(-30);
04486       }
04487 
04488       hor_offset  = -hor_offset     + HOR_HALF(yy);
04489       MoveHor(hor_offset);
04490       vert_offset = (vert_offset - 30) + VERT_HALF(yy);
04491       MoveVert(-vert_offset);
04492 
04493       PMPLine((int)yy, 0, (int)(xx - yy));
04494 
04495     } else if ( (yy < xx) && (xx > 0) ) {
04496 
04497       /* fprintf(ERR_STREAM, "hori rule: w=%d, x=%d, y=%d\n",(int)yy,(int)(xx-yy),0);*/
04498 
04499       hor_offset  = HOR_HALF(yy);
04500       vert_offset = VERT_HALF(yy);
04501 
04502       MoveHor(hor_offset);
04503       MoveVert(-vert_offset);
04504 
04505       PMPLine((int)yy, 0, (int)(xx - yy));
04506     } else if ( (xx < yy) && (yy > 0)) {
04507 
04508       hor_offset  = HOR_HALF(xx);
04509       vert_offset = VERT_HALF(xx);
04510       /*
04511         fprintf(ERR_STREAM, "move: x=%d, y=%d\n",hor_offset,-vert_offset);
04512         fprintf(ERR_STREAM, "vert rule: w=%d, x=%d, y=%d\n",(int)xx,0,(int)-(yy-xx));
04513         */
04514       MoveHor(hor_offset);
04515       MoveVert(-vert_offset);
04516 
04517       PMPLine((int)xx, (int)-(yy - xx), 0);
04518     } else if (xx == yy) {
04519       short     y0;  /* small square box!! */
04520 
04521       y0 = (short)yy / 2;
04522       hor_offset  = HOR_HALF(y0);
04523       MoveHor(hor_offset);
04524       vert_offset = VERT_HALF(y0);
04525       MoveVert(-vert_offset);
04526       ll = (short)xx - y0;
04527 
04528       PMPLine((int)y0, 0, ll);
04529 
04530       hor_offset  = - (ll + hor_offset);
04531       vert_offset = (y0 - vert_offset);
04532 
04533       yy -= (long4)y0;
04534       hor_offset  += HOR_HALF(yy);
04535       MoveHor(hor_offset);
04536       vert_offset += VERT_HALF(yy);
04537       MoveVert(-vert_offset);
04538 
04539       PMPLine((int)yy, 0, (int)xx - yy);
04540     }
04541 #endif
04542 #ifdef LJ
04543     if (last_ry + 1 < yy) yy = last_ry + 1;
04544     if (last_rx < 0) xx += last_rx;
04545 
04546     if ((int)pgsiz_dots > 0 && (int)last_ry > (int)pgsiz_dots)
04547       yy += (long4)pgsiz_dots - (long4)last_ry;
04548 
04549     if ((yy>0) && (xx>0))
04550       EMIT4("\033*p-%ldY\033*c%lda%ldbP", 
04551             (long)yy - 1, (long)xx, (long)yy);
04552 #endif
04553     last_rx = last_ry = UNKNOWN;       /* next time full positioning */
04554   }
04555   if (Set)
04556     h += b;
04557 }
04558 
04559 
04560 
04561 /*-->FormFeed*/
04562 /**********************************************************************/
04563 /*****************************  FormFeed ******************************/
04564 /**********************************************************************/
04565 #if NeedFunctionPrototypes
04566 void FormFeed(void)
04567 #else
04568 void FormFeed()
04569 #endif
04570 {
04571 
04572 #ifdef IBM3812
04573   unsigned short pages;
04574   if ( ndone == 0 && FirstAlternate ){
04575     for (pages = 1; pages < ncopies; pages++) {
04576       PMPout(2, "\321\300"); /* PMP-command xD1C0 */
04577     }
04578     PMPout(2, "\321\100"); /* PMP-command xD140 */
04579   } else {
04580     for (pages = 1; pages < ncopies; pages++){
04581       PMPout(2, "\321\200"); /* PMP-command xD180 */
04582     }
04583     PMPout(2, "\321\0"); /* PMP-command xD100 */
04584   }
04585 #endif
04586 #ifdef LJ
04587   EMITC('\f');
04588 #endif
04589 }
04590 /*------------------------ end dvimisc.c -------------------------------*/
04591 
04592 
04593 
04594 
04595 /*------------------------ begin dvifont.c -----------------------------*/
04596 /*-->GetFontDef*/
04597 /**********************************************************************/
04598 /**************************** GetFontDef  *****************************/
04599 /**********************************************************************/
04600 #if NeedFunctionPrototypes
04601 void GetFontDef(void)
04602 #else
04603 void GetFontDef()
04604 #endif
04605 /***********************************************************************
04606    Read the font  definitions as they  are in the  postamble of the  DVI
04607    file.
04608 ***********************************************************************/
04609 {
04610   unsigned char   byte;
04611   while (((byte = (unsigned char) NoSignExtend(dvifp, 1)) >= FNT_DEF1) &&
04612          (byte <= FNT_DEF4)) {
04613     switch (byte) {
04614     case FNT_DEF1:
04615       ReadFontDef( NoSignExtend(dvifp, 1));
04616       break;
04617     case FNT_DEF2:
04618       ReadFontDef( NoSignExtend(dvifp, 2));
04619       break;
04620     case FNT_DEF3:
04621       ReadFontDef( NoSignExtend(dvifp, 3));
04622       break;
04623     case FNT_DEF4:
04624       ReadFontDef( NoSignExtend(dvifp, 4));
04625       break;
04626     default:
04627       Fatal("Bad byte value in font defs");
04628       break;
04629     }
04630   }
04631   if (byte != POST_POST)
04632     Fatal("POST_POST missing after fontdefs");
04633 }
04634 
04635 
04636 
04637 
04638 /*-->OpenFontFile*/
04639 /**********************************************************************/
04640 /************************** OpenFontFile  *****************************/
04641 /**********************************************************************/
04642 #if NeedFunctionPrototypes
04643 void OpenFontFile(void)
04644 #else
04645 void OpenFontFile()
04646 #endif
04647 /***********************************************************************
04648     The original version of this dvi driver reopened the font file  each
04649     time the font changed, resulting in an enormous number of relatively
04650     expensive file  openings.   This version  keeps  a cache  of  up  to
04651     MAXOPEN open files,  so that when  a font change  is made, the  file
04652     pointer, pxlfp, can  usually be  updated from the  cache.  When  the
04653     file is not found in  the cache, it must  be opened.  In this  case,
04654     the next empty slot  in the cache  is assigned, or  if the cache  is
04655     full, the least used font file is closed and its slot reassigned for
04656     the new file.  Identification of the least used file is based on the
04657     counts of the number  of times each file  has been "opened" by  this
04658     routine.  On return, the file pointer is always repositioned to  the
04659     beginning of the file.
04660 ***********************************************************************/
04661 
04662 #if MAXOPEN > 1
04663 
04664 {
04665   int     i, least_used, current;
04666   struct pixel_list tmp;
04667   FILEPTR fid;
04668   struct font_entry *fp;
04669 
04670 #ifdef DEBUG
04671   if (Debug)
04672     fprintf(ERR_STREAM,"open font file %s\n", fontptr->name);
04673 #endif
04674   /*
04675     fprintf(ERR_STREAM,"? %lx == %lx\n", pfontptr,fontptr);
04676     */
04677   if ((pfontptr == fontptr) && (pxlfp != NO_FILE))
04678     return;         /* we need not have been called */
04679 
04680   if (fontptr->font_file_id == NO_FILE)
04681     return;         /* we need not have been called */
04682 
04683   tmp = pixel_files[1];
04684   current = 1;
04685   while (current <= nopen && tmp.pixel_file_id != fontptr->font_file_id) {
04686     ++current;
04687     tmp = pixel_files[current];
04688   }
04689   /* try to find file in open list */
04690 
04691   if (current <= nopen)       /* file already open */ {
04692     if ( pixel_files[current].pixel_file_id != NO_FILE ) {
04693       pxlfp = pixel_files[current].pixel_file_id;
04694       /* reposition to start of file */
04695       FSEEK(pxlfp, 0l, SEEK_SET);
04696     }
04697   } else {
04698     /* file not in open list          */
04699     if (nopen < MAXOPEN)    /* just add it to list    */
04700       current = ++nopen;
04701     else  {
04702       /* list full -- find least used file,     */
04703       /* close it, and reuse slot for new file  */
04704       least_used = 1;
04705       for (i = 2; i <= MAXOPEN; ++i)
04706         if (pixel_files[least_used].use_count > pixel_files[i].use_count)
04707           least_used = i;
04708       if ((fid = pixel_files[least_used].pixel_file_id) != NO_FILE) {
04709         /* mark file as being closed in the entry */
04710         fp = hfontptr;
04711         while (fp != NULL && fp->font_file_id != fid) 
04712           fp = fp->next;
04713         if (fp == NULL)
04714           Fatal("Open file %x not found in font entry list.\n", fid);
04715         else {
04716           fp->font_file_id = FPNULL;
04717         }
04718         BCLOSE( fid );
04719       }
04720 #ifdef DEBUG
04721       if (Debug)
04722         fprintf(ERR_STREAM,"\n__reuse slot %d\n", least_used);
04723 #endif
04724       current = least_used;
04725     }
04726     if ((pxlfp = BINOPEN(fontptr->name)) == FPNULL) {
04727       Warning("PXL-file %s could not be opened", fontptr->name);
04728       pxlfp = NO_FILE;
04729     } else {
04730 #ifdef DEBUG
04731       if (Debug)
04732         fprintf(ERR_STREAM,"Opening File  <%s> /%p/, Size(font_entry)=%d\n",
04733                 fontptr->name, pxlfp, sizeof(struct font_entry ));
04734 #endif
04735 
04736     }
04737     pixel_files[current].pixel_file_id = pxlfp;
04738     pixel_files[current].use_count = 0;
04739   }
04740   pfontptr = fontptr;         /* make previous = current font */
04741   fontptr->font_file_id = pxlfp;      /* set file identifier */
04742   pixel_files[current].use_count++;   /* update reference count */
04743 #ifndef USEPXL
04744   gfin = pxlfp;
04745 #endif
04746 }
04747 
04748 #else /* ! MAXOPEN > 1 */
04749 
04750 {
04751   FILEPTR f;
04752   struct font_entry *fp;
04753 
04754   if (pfontptr == fontptr && pxlfp != NO_FILE)
04755     return;         /* we need not have been called */
04756   if (fontptr->font_file_id == NO_FILE)
04757     return;         /* we need not have been called */
04758 
04759   f = pfontptr->font_file_id;
04760   if (f != FPNULL) {
04761     if (pxlfp != FPNULL) {
04762       fp = hfontptr;
04763       while ((fp != NULL) && (fp->font_file_id != f))
04764         fp = fp->next;
04765 
04766       if (fp == NULL) 
04767         Fatal("Open file %x not found in font entry list.\n",f);
04768       else 
04769         fp->font_file_id = FPNULL;
04770     }
04771     BCLOSE(f);
04772   }
04773   if ((pxlfp = BINOPEN(fontptr->name)) == FPNULL) {
04774     Warning("PXL-file %s could not be opened", fontptr->name);
04775     pxlfp = NO_FILE;
04776   }
04777   pfontptr = fontptr;
04778   fontptr->font_file_id = pxlfp;
04779 }
04780 
04781 #endif
04782 
04783 
04784 /*-->PixRound*/
04785 /**********************************************************************/
04786 /*****************************  PixRound  *****************************/
04787 /**********************************************************************/
04788 #if NeedFunctionPrototypes
04789 long4 PixRound(long4 x, long4 conv)
04790 #else
04791 long4 PixRound(x, conv)  /* return rounded number of pixels */
04792 long4    x;              /* in DVI units     */
04793 long4    conv;           /* conversion factor */
04794 #endif
04795 {
04796   return((x + conv) / conv);
04797 }
04798 
04799 
04800 #ifdef LJ_RESIDENT_FONTS
04801 /*-->TryResident*/
04802 /**********************************************************************/
04803 /****************************  TryResident  ***************************/
04804 /**********************************************************************/
04805 #if NeedFunctionPrototypes
04806 bool TryResident(struct font_entry *fontptr)
04807 #else
04808 bool TryResident(fontptr)
04809 struct font_entry *fontptr;
04810 #endif
04811 {
04812   extern bool tfm_read_info();
04813   tfm_info_type tfm_info;
04814 
04815   /* To determine if a font is resident, check for a special family
04816      value (header bytes 12..16 in the TFM file). This seems cleaner,
04817      and certainly more convenient, than somehow reading an external
04818      ljfonts.map file in which we'd have to specify information for all
04819      the resident fonts.  */
04820   if (tfm_read_info(fontptr->n, &tfm_info)
04821       && tfm_info.family[0]
04822       && strcmp((char *)tfm_info.family, "HPAUTOTFM") == 0) {
04823     unsigned i;
04824     double factor = fontptr->s / (double)0x100000;
04825 
04826     resident_count++;
04827     fontptr->resident_p = _TRUE;
04828     strcpy(fontptr->symbol_set, (char *)tfm_info.coding_scheme);
04829     fontptr->resid = tfm_info.typeface_id;
04830     fontptr->spacing = tfm_info.spacing;
04831     fontptr->style = tfm_info.style;
04832     fontptr->weight = tfm_info.weight;
04833 
04834     if (fontptr->spacing == SPACING_FIXED) {
04835       /* Have to select the point in pitch (characters per inch) instead
04836          of point size, and thus have to figure out the pitch that
04837          corresponds to the point size at which the font is used.
04838 
04839          To do this, take the width of the interword space, and see how
04840          many of those characters will fit in the at size. Then convert
04841          to how many characters will fit in one inch. That's our pitch.
04842 
04843          All the builtin LJ4 fonts that are monospaced are Intellifont,
04844          which have 72.307 points per inch. Not that it really makes any
04845          difference. We don't worry about this elsewhere, since all
04846          point sizes are rounded to .25pt anyway, which is more than the
04847          difference between the various definitions of `point'. */
04848       double ds_in_points = fontptr->s / 65536.0;
04849       double w_in_points = tfm_info.interword / (double)0x100000;
04850       if (ds_in_points == 0 || w_in_points == 0) {
04851         /* Avoid division by zero if no interword space. */
04852         Warning("%s: Can't determine pitch for this monospaced font.\n",
04853                  fontptr->n);
04854         fontptr->pitch = 10; /* Result will look awful, which is good. */
04855       } else {
04856         fontptr->pitch = 72.307 / (ds_in_points * w_in_points);
04857       }
04858     }
04859 
04860 #ifdef DEBUG
04861     if (Debug)
04862       fprintf(ERR_STREAM,"%6s: typeface=%u\tspacing=%u\tstyle=%u\tweight=%d\n",
04863               fontptr->n, fontptr->resid, fontptr->spacing,
04864               fontptr->style, fontptr->weight);
04865 #endif
04866     for (i = 0; i < NFNTCHARS; i++) {
04867       struct char_entry *cptr = &(fontptr->ch[i]);
04868       cptr->tfmw = (long4)(tfm_info.widths[i] * factor);
04869       cptr->cw = ((fontptr->ch[i].tfmw) / (double)hconv) + .5;
04870       cptr->width =
04871         cptr->height =
04872         cptr->xOffset =
04873         cptr->yOffset =
04874         cptr->yyOffset = 0;
04875     }
04876     return _TRUE;
04877   } else {
04878     fontptr->resident_p = _FALSE;
04879 
04880     if (tfm_info.family[0]
04881         && strcmp((char *)tfm_info.family, "UNSPECIFIED") == 0) {
04882       Warning("font family for %s is UNSPECIFIED; need to run dvicopy?",
04883               fontptr->n);
04884       fontptr->font_file_id = NO_FILE;
04885       return _TRUE;
04886     } else {
04887       return _FALSE;
04888     }
04889   }
04890 }
04891 #endif
04892 
04893 
04894 
04895 /*-->ReadFontDef*/
04896 /**********************************************************************/
04897 /****************************  ReadFontDef  ***************************/
04898 /**********************************************************************/
04899 
04900 #if NeedFunctionPrototypes
04901 unsigned char skip_specials(long4 *pkloc)
04902 #else
04903 unsigned char skip_specials(pkloc)
04904 long4    *pkloc;
04905 #endif
04906 {
04907   long4    i, j;
04908   register unsigned char  flag_byte;
04909   do {
04910     flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
04911     /*
04912       fprintf(ERR_STREAM,"flagbyte = %d, pkloc=%ld\n",(int)flag_byte,(long)*pkloc);
04913       */
04914 
04915     (*pkloc) ++;
04916     if (flag_byte  >= 240)
04917       switch (flag_byte) {
04918       case 240:
04919       case 241:
04920       case 242:
04921       case 243 : {
04922         i = 0;
04923         for (j = 240; j <= (long4)flag_byte; j++) {
04924           i = 256 * i + NoSignExtend(pxlfp, 1);
04925           (*pkloc) ++;
04926         }
04927         for (j = 1; j <= i; j++) {
04928           (void) NoSignExtend(pxlfp, 1);
04929           (*pkloc) ++;
04930         }
04931         break;
04932       }
04933       case 244 : {
04934         i = NoSignExtend(pxlfp, 4);
04935         (*pkloc) += 4;
04936         break;
04937       }
04938       case 245 :
04939         break;
04940       case 246 :
04941         break;
04942       case 247:
04943       case 248:
04944       case 249:
04945       case 250:
04946       case 251:
04947       case 252:
04948       case 253:
04949       case 254:
04950       case 255: {
04951         Fatal("Unexpected flagbyte %d!\n", (int)flag_byte);
04952       }
04953       }
04954   } while (!((flag_byte < 240) || (flag_byte == PK_POST)));
04955   return(flag_byte);
04956 }
04957 
04958 
04959 #if NeedFunctionPrototypes
04960 void ReadFontDef(long4 k)
04961 #else
04962 void ReadFontDef(k)
04963 long4    k;
04964 #endif
04965 {
04966   long4    t;
04967   unsigned short i;
04968   struct font_entry *tfontptr; /* temporary font_entry pointer   */
04969   struct char_entry *tcharptr; /* temporary char_entry pointer  */
04970   static int      plusid = 0;
04971   bool font_found = _FALSE;
04972 #ifdef LJ_RESIDENT_FONTS
04973   bool resident_font_located = _FALSE;
04974 #endif
04975 #ifdef LJ
04976   int depth, max_depth;
04977 #endif
04978 
04979 #ifdef DEBUG
04980   if (Debug)
04981     fprintf(ERR_STREAM,"Mallocating %d Bytes)...\n", sizeof(struct font_entry ));
04982 #endif
04983 
04984   if ((tfontptr = NEW(struct font_entry )) == NULL)
04985     Fatal("can't malloc space for font_entry");
04986 
04987   allocated_storage += sizeof(struct font_entry );
04988 
04989   tfontptr->next = hfontptr;
04990   tfontptr->font_file_id = FPNULL;
04991   fontptr = hfontptr = tfontptr;
04992   tfontptr->ncdl = 0;
04993   tfontptr->k = k;
04994   tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */
04995   tfontptr->s = NoSignExtend(dvifp, 4); /* space size */
04996   tfontptr->d = NoSignExtend(dvifp, 4); /* design size */
04997   tfontptr->a = (int)NoSignExtend(dvifp, 1); /* length for font name */
04998   tfontptr->l = (int)NoSignExtend(dvifp, 1); /* device length */
04999 
05000 #ifdef LJ
05001   tfontptr->max_width = tfontptr->max_height = tfontptr->max_yoff =
05002     max_depth = 0;
05003 #endif
05004 
05005   GetBytes(dvifp, tfontptr->n, tfontptr->a + tfontptr->l);
05006   tfontptr->n[tfontptr->a+tfontptr->l] = '\0';
05007 
05008   tfontptr->font_mag = 
05009     (long4)((ActualFactor((long4)(1000.0*tfontptr->s/(double)tfontptr->d+0.5))
05010              * ActualFactor(mag)
05011 #ifdef USEPXL
05012              * RESOLUTION * 5.0
05013 #else
05014              * RESOLUTION
05015 #endif
05016              ) + 0.5);
05017   /*
05018 printf("[%ld]=%lf * %lf * %lf + 0.5 = %ld\n",
05019     ((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
05020     ActualFactor((long4)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
05021     ActualFactor(mag),
05022     (double)RESOLUTION * 5,
05023     (long)tfontptr->font_mag );
05024 */
05025 
05026 #ifdef LJ_RESIDENT_FONTS
05027   /* Pass in the name; fills in resident_p and resid (if resident). */
05028 
05029   resident_font_located = (bool)TryResident(tfontptr);
05030 
05031   if (tfontptr->resident_p)
05032     return;
05033 
05034   if (!(resident_font_located)) {
05035 #endif
05036 
05037 #ifdef KPATHSEA
05038     {
05039       kpse_glyph_file_type font_ret;
05040       char *name;
05041       unsigned dpi
05042         = kpse_magstep_fix ((unsigned) (tfontptr->font_mag / 5.0 + .5),
05043                             RESOLUTION, NULL);
05044       tfontptr->font_mag = dpi * 5; /* save correct dpi */
05045       
05046       name = kpse_find_pk (tfontptr->n, dpi, &font_ret);
05047       if (name)
05048         {
05049           font_found = _TRUE;
05050           strcpy (tfontptr->name, name);
05051           free (name);
05052           
05053           if (!FILESTRCASEEQ (tfontptr->n, font_ret.name)) {
05054               fprintf (stderr,
05055                        "dvilj: Font %s not found, using %s at %d instead.\n",
05056                        tfontptr->n, font_ret.name, font_ret.dpi);
05057               tfontptr->c = 0; /* no checksum warning */
05058             }
05059           else if (!kpse_bitmap_tolerance ((double)font_ret.dpi, (double) dpi))
05060             fprintf (stderr,
05061                      "dvilj: Font %s at %d not found, using %d instead.\n",
05062                      tfontptr->name, dpi, font_ret.dpi);
05063           if (G_verbose)
05064             fprintf(stderr,"%d: using font <%s>\n", plusid,tfontptr->name);
05065         }
05066       else
05067         {
05068           tfontptr->font_file_id = NO_FILE;
05069           fprintf (stderr,
05070             "dvilj: Font %s at %u not found, characters will be left blank.\n",
05071             tfontptr->n, dpi);
05072         }
05073     }
05074 #else /* not KPATHSEA */
05075     if (!(findfile(PXLpath,
05076                    tfontptr->n,
05077                    tfontptr->font_mag,
05078                    tfontptr->name,
05079                    _FALSE,
05080                    0))) {
05081       Warning(tfontptr->name); /* contains error messsage */
05082       tfontptr->font_file_id = NO_FILE;
05083 #ifdef __riscos
05084       MakeMetafontFile(PXLpath, tfontptr->n, tfontptr->font_mag);
05085 #endif
05086     }
05087     else {
05088       font_found = _TRUE;
05089       if (G_verbose)
05090         fprintf(ERR_STREAM,"%d: using font <%s>\n", plusid, tfontptr->name);
05091     }
05092 #endif /* not KPATHSEA */
05093 
05094 #ifdef LJ_RESIDENT_FONTS
05095   }
05096 #endif
05097 
05098   tfontptr->plusid = plusid;
05099   plusid++;
05100 
05101   /* sprintf(tfontptr->psname,"%s.%ld.%d",
05102        tfontptr->n, (long)tfontptr->font_mag, (long)tfontptr->plusid);*/
05103 
05104 #ifdef LJ
05105   if (plusid >= HANDLE_MAX_FONTS)
05106     Fatal("can handle only %d fonts! ask a wizzard...\n",
05107           HANDLE_MAX_FONTS);
05108 #endif
05109   if (tfontptr != pfontptr) {
05110     if (font_found) 
05111       OpenFontFile();
05112     else
05113       pxlfp = NO_FILE;
05114   }
05115 #ifdef USEPXL
05116   if ( pxlfp == NO_FILE ) {        /* allow missing pxl files */
05117     tfontptr->magnification = 0;
05118     tfontptr->designsize = 0;
05119 #endif
05120     for (i = FIRSTFNTCHAR; i <= LASTFNTCHAR; i++) {
05121       tcharptr = &(tfontptr->ch[i]);
05122 #ifdef USEPXL
05123       tcharptr->width = 0;
05124       tcharptr->height = 0;
05125       tcharptr->xOffset = 0;
05126       tcharptr->yOffset = 0;
05127 #endif
05128       tcharptr->where.isloaded = _FALSE;
05129       tcharptr->where.address.fileOffset = NONEXISTANT;
05130       tcharptr->tfmw = 0;
05131     }
05132 #ifdef USEPXL
05133     return;
05134   }
05135   t = NoSignExtend(pxlfp, 1);
05136   if (t == 0) {
05137     t = NoSignExtend(pxlfp, 1);
05138     t = NoSignExtend(pxlfp, 2);
05139     if (t == 1002)
05140       tfontptr->id = id1002;
05141     else if (t == 1001)
05142       tfontptr->id = id1001;
05143     else
05144       Fatal("Unknown Version of PXL-format\n");
05145   } else {
05146     if (t == PK_PRE) {
05147       unsigned char   temp_byte;
05148       temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
05149       if (temp_byte != PK_ID) 
05150         Fatal( "Wrong Version of pk file!  (%d should be 89)\n",
05151                (int)temp_byte);
05152       else
05153         tfontptr->id = pk89;
05154     } else
05155       Fatal("unknown font format in file <%s> !\n",fontptr->name);
05156   }
05157 
05158   if ((tfontptr->id == id1002) || (tfontptr->id == id1001)) {
05159     FSEEK(pxlfp, -20l, SEEK_END);
05160 
05161     t = NoSignExtend(pxlfp, 4);
05162     check_checksum (tfontptr->c, t, tfontptr->name);
05163 
05164     tfontptr->magnification = NoSignExtend(pxlfp, 4);
05165     tfontptr->designsize    = NoSignExtend(pxlfp, 4);
05166         
05167     if (tfontptr->id == id1001)
05168       FSEEK(pxlfp, (long)(NoSignExtend(pxlfp, 4) * 4), SEEK_SET);
05169     else
05170       FSEEK(pxlfp, (long)NoSignExtend(pxlfp, 4), SEEK_SET);
05171 
05172     for (i = FIRSTFNTCHAR; i <= 127; i++) {   /* only defined for 7bit*/
05173       tcharptr = &(tfontptr->ch[i]);
05174       tcharptr->width   = (unsigned short) NoSignExtend(pxlfp, 2);
05175       tcharptr->height  = (unsigned short) NoSignExtend(pxlfp, 2);
05176       tcharptr->xOffset = (short) SignExtend(pxlfp, 2);
05177       tcharptr->yOffset = (short) SignExtend(pxlfp, 2);
05178       tcharptr->where.isloaded = _FALSE;
05179       if (tfontptr->id == id1001)
05180         tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4) * 4;
05181       else
05182         tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4);
05183       tcharptr->tfmw = (long4)
05184         (   (double)(NoSignExtend(pxlfp, 4))
05185             * (double)tfontptr->s / (double)0x100000 );
05186       tcharptr->cw = (long4)(((double)tcharptr->tfmw/(double)hconv) + 0.5);
05187 
05188       if (tcharptr->width  > CHAR_WIDTH_LARGE  ||
05189           tcharptr->height > CHAR_HEIGTH_LARGE )
05190         tcharptr->charsize = LARGE_SIZE;
05191       else
05192         tcharptr->charsize = SMALL_SIZE;
05193 #ifdef LJ
05194 #undef max
05195 # define  max(x,y)       if ((y)>(x)) x = y
05196 
05197       max(tfontptr->max_width,tcharptr->width);
05198       max(tfontptr->max_height,tcharptr->height);
05199       if (tcharptr->yOffset > 0  && (int)tfontptr->max_yoff < (int)tcharptr->yOffset)
05200         tfontptr->max_yoff = tcharptr->yOffset;
05201       if ((depth = tcharptr->height - tcharptr->yOffset)>max_depth)
05202         max_depth = depth;
05203 #endif
05204 
05205     }
05206 #ifdef LJ
05207     tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
05208       tfontptr->max_yoff+1;
05209 #endif
05210   } else { /* PK 89 format */
05211     unsigned char   temp_byte;
05212     register unsigned char  flag_byte;
05213     long4    hppp, vppp, pkloc, packet_length;
05214     int     car, ii;
05215 
05216     /* read comment */
05217     for ( ii = temp_byte = (unsigned char)NoSignExtend(pxlfp, 1); ii>0; ii--) {
05218       flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
05219 #ifdef DEBUG
05220       if (Debug) fprintf(ERR_STREAM, "%c", flag_byte );
05221 #endif
05222     }
05223 #ifdef DEBUG
05224     if (Debug) fprintf(ERR_STREAM, "\n");
05225 #endif
05226     pkloc = 3 + (int)temp_byte;
05227     tfontptr->designsize = NoSignExtend(pxlfp, 4);
05228 
05229     t = NoSignExtend(pxlfp, 4);
05230     check_checksum (tfontptr->c, t, tfontptr->name);
05231 
05232     hppp = NoSignExtend(pxlfp, 4);
05233     vppp = NoSignExtend(pxlfp, 4);
05234     if (hppp != vppp)
05235       Warning("aspect ratio is %ld:%ld (should be 1:1)!", 
05236               (long)hppp, (long)vppp);
05237     tfontptr->magnification = (long4)(hppp * 72.27 * 5 / 65536l + 0.5);
05238 
05239     pkloc += 16;
05240     flag_byte = skip_specials(&pkloc);
05241 
05242     while (flag_byte != PK_POST) {
05243       if ((flag_byte & 7) == 7) {
05244         /* fprintf(ERR_STREAM,"\nRead long character preamble\n"); */
05245 
05246         packet_length = (unsigned long4)NoSignExtend(pxlfp,4);
05247         if ((car = (int)NoSignExtend(pxlfp, 4)) > (LASTFNTCHAR))
05248           Fatal("Bad character (%d) in PK-File\n",(int)car);
05249 
05250         tcharptr = &(tfontptr->ch[car]);
05251         tcharptr->where.address.fileOffset = pkloc;
05252         /* set pkloc to end_of_packet */
05253         pkloc += packet_length + 8;
05254 
05255         tcharptr->tfmw = NoSignExtend(pxlfp, 4);
05256         (void) NoSignExtend(pxlfp, 4); /* horesc not used */
05257         (void) NoSignExtend(pxlfp, 4); /* not used */
05258 
05259         tcharptr->width   = (unsigned short) NoSignExtend(pxlfp, 4);
05260         tcharptr->height  = (unsigned short) NoSignExtend(pxlfp, 4);
05261         tcharptr->xOffset = (short) SignExtend(pxlfp, 4);
05262         tcharptr->yOffset = (short) SignExtend(pxlfp, 4);
05263         tcharptr->where.isloaded = _FALSE;
05264       } else if (flag_byte & 4) {
05265         /* fprintf(ERR_STREAM,"Read extended short character preamble\n"); */
05266 
05267         packet_length = ((long4)flag_byte & 3) * 65536l +
05268           (unsigned short) NoSignExtend(pxlfp, 2);
05269         if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
05270           Fatal("Bad character (%d) in PK-File\n",(int)car);
05271 
05272         tcharptr = &(tfontptr->ch[car]);
05273         tcharptr->where.address.fileOffset = pkloc;
05274         /* set pkloc to end_of_packet */
05275         pkloc += packet_length + 3;
05276 
05277         tcharptr->tfmw = NoSignExtend(pxlfp, 3);
05278         /*
05279           { register unsigned short t;
05280           t = (unsigned short) NoSignExtend(pxlfp, 1);
05281           tcharptr->tfmw = t * 65536l +
05282           (unsigned short) NoSignExtend(pxlfp, 2);
05283           }
05284           */
05285         /* horesc not used */
05286         (void) NoSignExtend(pxlfp, 2);
05287         tcharptr->width   = (unsigned short) NoSignExtend(pxlfp,2);
05288         tcharptr->height  = (unsigned short) NoSignExtend(pxlfp,2);
05289         tcharptr->xOffset = (short) SignExtend(pxlfp, 2);
05290         tcharptr->yOffset = (short) SignExtend(pxlfp, 2);
05291         tcharptr->where.isloaded = _FALSE;
05292       } else {
05293         /* fprintf(ERR_STREAM,"<Read short character preamble@>\n"); */
05294 
05295         packet_length = ((long4)flag_byte & 3) * 256 +
05296           NoSignExtend(pxlfp, 1);
05297         if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
05298           Fatal("Bad character (%d) in PK-File\n",(int)car);
05299 
05300         tcharptr = &(tfontptr->ch[car]);
05301         tcharptr->where.address.fileOffset = pkloc;
05302         /* set pkloc to end_of_packet */
05303         pkloc += packet_length + 2;
05304 
05305         tcharptr->tfmw = NoSignExtend(pxlfp, 3);
05306         /*
05307           { register unsigned short t;
05308           t = (unsigned short) NoSignExtend(pxlfp, 1);
05309           tcharptr->tfmw = t * 65536l +
05310           (unsigned short) NoSignExtend(pxlfp, 2);
05311           }
05312           */
05313         /* horesc not used */
05314         (void) NoSignExtend(pxlfp, 1);
05315         tcharptr->width   = (unsigned short) NoSignExtend(pxlfp,1);
05316         tcharptr->height  = (unsigned short) NoSignExtend(pxlfp,1);
05317         tcharptr->xOffset = (short) SignExtend(pxlfp, 1);
05318         tcharptr->yOffset = (short) SignExtend(pxlfp, 1);
05319         tcharptr->where.isloaded = _FALSE;
05320       }
05321 
05322       tcharptr->tfmw = (long4)
05323         ( tcharptr->tfmw * (double)tfontptr->s / (double)0x100000 );
05324 
05325       tcharptr->cw = (long4)(((double)tcharptr->tfmw / (double)hconv) + 0.5);
05326 
05327       if (tcharptr->width  > CHAR_WIDTH_LARGE  ||
05328           tcharptr->height > CHAR_HEIGTH_LARGE )
05329         tcharptr->charsize = LARGE_SIZE;
05330       else
05331         tcharptr->charsize = SMALL_SIZE;
05332 
05333 #ifdef LJ
05334       /*
05335         printf("char=%d: this=%d, max_width=%d, this=%d,max_height=%d, this=%d,max_yoff=%d\n",
05336         car, tcharptr->width, tfontptr->max_width,
05337         tcharptr->height,tfontptr->max_height,
05338         tcharptr->yOffset,tfontptr->max_yoff);
05339         */
05340       max(tfontptr->max_width, tcharptr->width);
05341       max(tfontptr->max_height,tcharptr->height);
05342       if (tcharptr->yOffset > 0  && (int)tfontptr->max_yoff < (int)tcharptr->yOffset)
05343         tfontptr->max_yoff = tcharptr->yOffset;
05344 
05345       if ((depth = tcharptr->height - tcharptr->yOffset) > max_depth)
05346         max_depth = depth;
05347 #endif
05348       /*
05349         fprintf(ERR_STREAM,"char=%d, yotcharptr=%lx, flag_byte=%d, font=%lx\n",car, tcharptr,flag_byte,tfontptr);
05350         */
05351       tcharptr->flag_byte = flag_byte;
05352       FSEEK(pxlfp, (long)pkloc, SEEK_SET);
05353       flag_byte = skip_specials(&pkloc);
05354 
05355     } /* end of while */
05356 #ifdef LJ
05357     tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
05358       tfontptr->max_yoff+1;
05359 #endif
05360 
05361     /*
05362 printf("fontid=%d: max_width=%u, max_height=%d, max_yoff=%u\n",
05363         tfontptr->plusid, tfontptr->max_width,
05364         tfontptr->max_height, tfontptr->max_yoff);
05365         */
05366 
05367 #else /* USEPXL */
05368     if ( pxlfp == NO_FILE )        /* allow missing pxl files */
05369       return;
05370 
05371     gfin = pxlfp;
05372     seekpost();
05373     readpost();
05374     check_checksum (tfontptr->c, checksum, tfontptr->name);
05375 
05376     for(i = FIRSTFNTCHAR; i<=LASTFNTCHAR; i++) {
05377       if (char_exists[i]) {
05378         tcharptr = &(tfontptr->ch[i]);
05379         tcharptr->tfmw = (long4)(((float)tfm_wd[i]*(float)tfontptr->s) /
05380                                  (float)((long4)1l<<20));
05381         tcharptr->where.address.fileOffset = char_pointer[i];
05382       }
05383 # ifdef LJ
05384       /*                 GF USER PLEASE CHECK IF THIS CODE WORKS
05385                          tfontptr->max_width = gf_font_max_m;
05386                          tfontptr->max_height = gf_font_max_n;
05387                          tfontptr->max_yoff = gf_font_min_n;
05388                          */
05389 # endif /* LJ */
05390 #endif /* USEPXL */
05391 
05392 /*****************************************************************************/
05393   /*if (tcharptr->charsize==LARGE_SIZE)
05394     fprintf(ERR_STREAM,"%d:\t <%c> w=%d h=%d xO=%d yO=%d tfmw=%ld cw=%ld %d\n",
05395     i,(char) i,
05396     tcharptr->width,tcharptr->height,tcharptr->xOffset,tcharptr->yOffset,
05397     (long)tcharptr->tfmw, (long)tcharptr->cw, (int)(tcharptr->charsize));
05398     */
05399 /*****************************************************************************/
05400   }
05401 }
05402 
05403 
05404 
05405 
05406 
05407 /*-->SetFntNum*/
05408 /**********************************************************************/
05409 /****************************  SetFntNum  *****************************/
05410 /**********************************************************************/
05411 #if NeedFunctionPrototypes
05412 void SetFntNum(long4 k, bool Emitting)
05413 #else
05414 void SetFntNum(k, Emitting)
05415 long4    k;
05416 bool Emitting;
05417 #endif
05418 /*  this routine is used to specify the font to be used in printing future
05419     characters */
05420 {
05421 #ifdef LJ
05422   static unsigned short plusid = 0;
05423 #endif
05424   fontptr = hfontptr;
05425   while ((fontptr != NULL) && (fontptr->k != k))
05426     fontptr = fontptr->next;
05427   if (fontptr == NULL)
05428     Fatal("font %ld undefined", (long)k);
05429   if (Emitting && fontptr->font_file_id != NO_FILE) {
05430     if (!fontptr->used_on_this_page
05431 #ifdef LJ_RESIDENT_FONTS
05432         && !fontptr->resident_p
05433 #endif
05434         ) {
05435       fontptr->used_on_this_page = _TRUE;
05436 #ifdef LJ
05437       if (++fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
05438         qfprintf(ERR_STREAM,"%s is font #%d font on this page!",
05439                   fontptr->n, fonts_used_on_this_page);
05440         qfprintf(ERR_STREAM," (max = %d) rastering characters!\n",
05441                   MAX_FONTS_PER_PAGE);
05442         rasterfont[fontptr->plusid] = _TRUE;
05443       }
05444 #endif
05445     }
05446 #ifdef DEBUG
05447     if (Debug)
05448       fprintf(ERR_STREAM, "Switching to font #%ld (%s).\n", k, fontptr->n);
05449 #endif
05450     /* activate font */
05451 #ifdef IBM3812
05452     sprintf(PMPformat, "\323%c", (unsigned char)fontptr->plusid);
05453     PMPout(2, PMPformat);
05454 #endif
05455 #ifdef LJ
05456     if (!rasterfont[fontptr->plusid]) {
05457 #ifdef LJ_RESIDENT_FONTS
05458       if (fontptr->resident_p) {
05459 #ifdef DEBUG
05460         if (Debug)
05461           fprintf(ERR_STREAM, "Resident font #%d.\n", fontptr->resid);
05462 #endif
05463         EMIT2("\033(%s", fontptr->symbol_set);
05464         EMIT4("\033(s%up%.2f%c",
05465               fontptr->spacing,
05466               /* height in points, or pitch */
05467               fontptr->spacing ? fontptr->s / 65536.0 : fontptr->pitch,
05468               fontptr->spacing ? 'v' : 'h' /* height or pitch? */
05469               );
05470         EMIT4("%us%db%uT",
05471               fontptr->style,       /* upright, italic, ... */
05472               fontptr->weight,      /* regular, bold, ... */
05473               fontptr->resid
05474               );
05475       } else
05476 #endif /* LJ_RESIDENT_FONTS */
05477         if (fontptr->plusid>0) EMIT2("\033(%dX", fontptr->plusid);
05478         else                   EMIT1("\033(X");
05479     }
05480     /* else fprintf(ERR_STREAM,"I am doing rasterfont for plusid=%d instead\n",
05481        fontptr->plusid);
05482        */
05483 #endif
05484   }
05485 #ifdef LJ    /* reassignment of printer font id  0.48 */
05486   else if (fontptr->font_file_id != NO_FILE
05487 #ifdef LJ_RESIDENT_FONTS
05488            && !fontptr->resident_p
05489 #endif
05490            ) {
05491     if (fontptr->ncdl == 0) {
05492 #ifdef DEBUG
05493       if (Debug)
05494         fprintf(ERR_STREAM, "Changing plusid from %d to %d\n",
05495                 fontptr->plusid, (int)plusid);
05496 #endif
05497       fontptr->plusid = plusid;
05498       plusid ++;
05499     }
05500   }
05501 #endif
05502 }
05503 
05504 
05505 
05506 /*-->SkipFontDef*/
05507 /**********************************************************************/
05508 /****************************  SkipFontDef  ***************************/
05509 /**********************************************************************/
05510 #if NeedFunctionPrototypes
05511 void SkipFontDef(void)
05512 #else
05513 void SkipFontDef()
05514 #endif
05515 {
05516   int     a, l;
05517   char    n[STRSIZE];
05518   
05519   (void) NoSignExtend(dvifp, 4);
05520   (void) NoSignExtend(dvifp, 4);
05521   (void) NoSignExtend(dvifp, 4);
05522   a = (int)NoSignExtend(dvifp, 1);
05523   l = (int)NoSignExtend(dvifp, 1);
05524   GetBytes(dvifp, n, a + l);
05525 }
05526 
05527     
05528 
05529 /*------------------------ end dvifont.c -------------------------------*/
05530 
05531 /*-->Fatal*/
05532 /**********************************************************************/
05533 /******************************  Fatal  *******************************/
05534 /**********************************************************************/
05535 void
05536 #if NeedVarargsPrototypes
05537 Fatal (char *fmt, ...)
05538 #else
05539 Fatal(va_alist)      /* issue a fatal error message */
05540      va_dcl
05541 #endif
05542 {
05543 #if !NeedVarargsPrototypes
05544   const char *fmt;
05545 #endif
05546   va_list args;
05547 
05548 #if NeedVarargsPrototypes
05549   va_start(args, fmt);
05550 #else
05551   va_start(args);
05552   fmt = va_arg(args, const char *);
05553 #endif
05554   fprintf(ERR_STREAM, "\n");
05555   fprintf(ERR_STREAM, "%s: FATAL--", G_progname);
05556   vfprintf(ERR_STREAM, fmt, args);
05557 
05558   fprintf(ERR_STREAM, "\n\n");
05559   va_end(args);
05560   CloseFiles();
05561 #ifndef vms
05562   exit(2);
05563 #else
05564   exit(SS$_ABORT);
05565 #endif
05566 }
05567 
05568 
05569 
05570 /*-->Warning*/
05571 /**********************************************************************/
05572 /*****************************  Warning  ******************************/
05573 /**********************************************************************/
05574 void                           /* issue a warning */
05575 #if NeedVarargsPrototypes
05576 Warning(char *fmt, ...)
05577 #else
05578 Warning(va_alist)
05579      va_dcl
05580 #endif
05581 {
05582 #if !NeedVarargsPrototypes
05583   const char *fmt;
05584 #endif
05585   va_list args;
05586 
05587 #if NeedVarargsPrototypes
05588   va_start(args, fmt);
05589 #else
05590   va_start(args);
05591   fmt = va_arg(args, const char *);
05592 #endif
05593 
05594 #ifndef vms
05595   G_errenc = 1;
05596 #else
05597   G_errenc = (SS$_ABORT | STS$M_INHIB_MSG);  /* no message on screen */
05598 #endif
05599   if ( G_nowarn || G_quiet )
05600     return;
05601   
05602   fprintf(ERR_STREAM, "%s: warning: ", G_progname);
05603   vfprintf(ERR_STREAM, fmt, args);
05604   fprintf(ERR_STREAM, "\n");
05605   va_end(args);
05606 }