home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / dviljk / dvi2xx.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  152KB  |  4,772 lines

  1. #define VERSION "dvilj version 2.5"
  2. /**********************************************************************
  3.  ****************************  Intro  *********************************
  4.  **********************************************************************
  5.  * This program translates TeX's DVI-Code into device dependent
  6.  * code of either the
  7.  *
  8.  *     -   HP-LASERJET+ and compatibles (PCL), or the
  9.  *     -   IBM 3812 pageprinter
  10.  *
  11.  * depending on the preprocessor switches specified before compilation.
  12.  * The program is written to run on a PC XT/AT/PS2 under MS-DOS. It can
  13.  * be compiled nicely with MSC Rel. 3.0-5.1 with option -AL (large memory
  14.  * model).  Take care that in the CONFIG.SYS file the FILES parameter
  15.  * is set to 20; otherwise reduce MAXOPEN.  640K are recommended.
  16.  * I use link option /stack:9000 to increase runtime stack.
  17.  * It also works without modifications under Unix System V.
  18.  **********************************************************************
  19.  *            Adapted for the PC:    Gustaf Neumann
  20.  *            +1002 stuff        University of Economics
  21.  *            +3812 support      Augasse 2-6
  22.  *            +Output buffering      A-1090 Vienna, AUSTRIA
  23.  *            +lpt binary support    Tel. *43-222-340525/533
  24.  *            +pk-89 stuff                   773
  25.  *            +pixelpaths
  26.  *            +alternative directory structure
  27.  *            +code compiles also under Unix V (HP/UX)
  28.  *                      (thx Michael Haberler)
  29.  *            +huge characters (a character bigger than 32K)
  30.  *                      formats PXL1001 and PXL 1002
  31.  *                     (use: raster graphics)
  32.  *            +reduction of the produced code
  33.  *            +new options -X -Y -c -g
  34.  *            +changed options -r (LJ now default from first to last)
  35.  *                     -x,-y  (accept floats)
  36.  *            +new option -z for LJ: print testpage containing
  37.  *                     pagecounter after printjob
  38.  *            +try to overcome font limit on LJ (max 16 fonts/page) and
  39.  *             (max 32 fonts/document):
  40.  *                     additional fonts are drawn as bitmap-
  41.  *                     graphics.
  42.  *            +allows to set character close to the paperedge on LJ
  43.  *            +gf-supprt (by Joe Kelsey joe@Pacer.com)
  44.  *                gf.c and gf.h from mitdevices/dvi2ps
  45.  *            +clipping of rules
  46.  *            +OS/2 defines from Rutger Berns, apprmb@hheouh50.bitnet
  47.  *
  48.  *            BITNET/EARN:       NEUMANN at AWIWUW11
  49.  **********************************************************************
  50.  * fixes in LJ-mode:  rule-drawing,
  51.  *            characters with 127<=height<=200
  52.  *            reset printer at beginning and end of each job
  53.  *            better positioning of rules
  54.  * 30.1.89 (0.48) bug fixed for files containing >32 fonts (thanks A. Brosig),
  55.  *                different font assignment heuristic
  56.  * fixes in 3812-mode:  14.juli 87  positioning of rastered characters
  57.  *            better positioning of rules
  58.  * general fixes
  59.  * 1.1.88         page origin set to 1in/1in (hopefully everywhere)
  60.  * 22.7.88        reset y-position for each page-eject
  61.  * 15.1.89        fixing bug is space allocation for EmitFileName
  62.  *                (thanks to Bernhard Simon)
  63.  * 15.3.91 (0.49) landscape support for lj ii p, lj iii and lj 2000 
  64.  *                fixing rule drawing problems for IBM3812 in landcape mode,
  65.  *                256 character clean (lj family and IBM3812) 
  66.  * 5.5.91 (0.50)  -DSEVENBIT added for older LJ-emulations
  67.  *                -D1, -D2, -D-, -D1-, -D2- options added due to suggestions 
  68.  *                from Tomasz Wolniewicz
  69.  **********************************************************************
  70.  * Preprocessor switches:
  71.  *      #define DEBUG    for massive printing of trace information
  72.  *               when -d cmdline option specified
  73.  *      #define IBM3812  produce output for the IBM3812 pageprinter
  74.  *      #define LJ       produce output for the HP Laserjet+ or LJ II
  75.  *      #define LJ2P     produce output for the HP Laserjet LJ IIP, LJ III
  76.  *                       or LaserJet 2000
  77.  *      #define LJ_LARGE_FONT_MEMORY  large FONT Memory for LJ printer family
  78.  *      #define DRAWGLYPH draws PK-Glyphs on stderr
  79.  *      #define USEPXL   use PXL and PK fonts rather than gf fonts
  80.  */
  81. /**********************************************************************
  82.  ************************  Global Definitions  ************************
  83.  **********************************************************************/
  84. /* #define IBM3812 */
  85. /* #define LJ */
  86. /* #define DRAWGLYPH */
  87.  
  88. #define KPATHSEA
  89. #ifdef KPATHSEA
  90. #include <kpathsea/config.h>
  91. #include <kpathsea/c-limits.h>
  92. #include <kpathsea/c-memstr.h>
  93. #include <kpathsea/magstep.h>
  94. #include <kpathsea/proginit.h>
  95. #include <kpathsea/progname.h>
  96. #include <kpathsea/tex-glyph.h>
  97. #else
  98. #include <string.h>
  99. #include <stdio.h>
  100. #ifdef  unix
  101. #include <limits.h>
  102. #endif
  103. #endif
  104.  
  105. #include "config.h"
  106. #include "commands.h"
  107. #include <signal.h>
  108. #include <ctype.h>
  109. #ifdef vms
  110. #include <file.h>
  111. #else
  112. #include <fcntl.h>
  113. #endif
  114. #ifdef MSDOS
  115. #include <dos.h>     /* only for binaryopen on device  */
  116. #endif
  117.  
  118. #define  DVIFORMAT     2
  119. #define  UNKNOWN      -1
  120. #define  FIRSTFNTCHAR  0
  121.  
  122. #ifdef   OPEN_MAX                    /* ... in a friendly unix system  */
  123. #ifndef vms
  124. #define  MAXOPEN_OS    (OPEN_MAX - 8)
  125. #else
  126. #define  MAXOPEN_OS    12     /* OPEN_MAX seems to be 8 on VMS systems */
  127. #endif
  128. #else
  129. #define  MAXOPEN_OS    12     /* limit on number of open font files */
  130. #endif
  131.  
  132. #ifdef LJ_RESIDENT_FONTS
  133. /* we have to read tfm files as well */
  134. #define  MAXOPEN       (MAXOPEN_OS - 1)
  135. #else
  136. #define  MAXOPEN       MAXOPEN_OS
  137. #endif
  138.  
  139. #define  NFNTCHARS       LASTFNTCHAR+1
  140. #define  STACK_SIZE      100     /* DVI-stack size                     */
  141. #define  NONEXISTANT     -1      /* offset for PXL files not found     */
  142. #define  NO_FILE        ((FILE *)-1)
  143. #define  NEW(A) ((A *)  malloc(sizeof(A)))
  144. #define  EQ(a,b)        (strcmp(a,b)==0)
  145. #define  MM_TO_PXL(x)   (int)(((x)*RESOLUTION*10)/254)
  146. #define  PT_TO_PXL(x)   (int)((long4)((x)*RESOLUTION*100l)/7224)
  147. #define  PT_TO_DVI(x)   (long4)((x)*65536l)
  148. #define  BOPENCMD fopen
  149. #define  BINOPEN(f) BOPENCMD(f,READ_BINARY)
  150. /* SMALL_SIZE characters are loaded into font storage of the printer   */
  151. /* LARGE_SIZE characters are rastered                                  */
  152. /* HUGE_SIZE characters are not loaded into the memory of the host     */
  153. #define  SMALL_SIZE (unsigned char) 0
  154. #define  LARGE_SIZE (unsigned char) 1
  155. #define  HUGE_SIZE  (unsigned char) 2
  156. #define  HUGE_CHAR_PATTERN 32767l
  157. #define  BYTES_PER_PIXEL_LINE 500    /* max number of bytes per pixel line */
  158.  
  159.  
  160. #define PK_POST 245
  161. #define PK_PRE 247
  162. #define PK_ID 89
  163.  
  164. /* to speedup the program a little: redefinition of PixRound and PutWord */
  165. /*#define PIXROUND(x,c) ((((double)x+(double)(c>>1))/(double)c)+0.5)*/
  166. #define PIXROUND(x,c) (((x)+c)/c)
  167. #define PUTWORD(w)  EMITC((char)(w>>8)&0xff); EMITC((char)w&0xff)
  168. /*************************************************************************/
  169. #define  EMIT            fprintf              /* output a formatted string   */
  170. #ifndef vms
  171. # define  EMITB(len,b)   fwrite(b,1,len,outfp)  /* output binary data of len */
  172. #else
  173.     /* VMS doesn't like to use fwrite on a file with fixed record sizes,
  174.        so use number of putc calls */
  175. # define  EMITB(len,b)   for (kk = 0;kk < len; kk++) putc(*(b+kk),outfp);
  176. #endif
  177. #define  EMITWORD(w)     PUTWORD((w))        /* output a 2 byte word of data */
  178.  
  179. #define  MoveOver(b)  h += (long4) b
  180. #define  MoveDown(a)  v += (long4) a
  181. #define  qfprintf if (!G_quiet) fprintf
  182. #define  qprintf  if (!G_quiet) printf
  183. #define  LARGER(a,b) (((a)>(b)) ? (a) : (b))
  184.  
  185. #ifdef IBM3812
  186. #define  PRINTER      "IBM 3812 pageprinter"
  187. #define  EMITC(c)      PMPoutC(c)               /* output a single character */
  188. #define  PMPcont(l)    PMPout(-1,(char *)l)         /* next l bytes continuous */
  189. #define  PMPflush      PMPout(0l,"")                     /* flush PMP-buffer */
  190. #define  EMITL(l,d)    PMPout((int)l,d)      /* EMIT-logical: via PMP-buffer */
  191. #define  hconvRESOLUTION   240
  192. #define  vconvRESOLUTION   240
  193. #define  CHAR_WIDTH_LARGE  100       /*  limit for loading into printer font */
  194. #define  CHAR_HEIGTH_LARGE 127       /*  limit for loading into printer font */
  195. #define  OUTBUFSIZE     20000        /*   size of output buffer for PMP cmds */
  196.                       /*   has to be less max(signed int)     */
  197. #define  MAXFONTSTORAGE      130000l /* font storage in the 3812 pageprinter */
  198. #define  EMITFILE_EXTENSION    ".pmp"      /* default extension of emit file */
  199. #define  XDEFAULTOFF    RESOLUTION        /* y default offset on page 1 inch */
  200. #define  YDEFAULTOFF    RESOLUTION        /* y default offset on page 1 inch */
  201. #define  CHARSTRINGMAX  80                /* bufferlength for SetString      */
  202. #define  MAX_PAGE_WIDTH  2040
  203. #define  MAX_PAGE_HEIGHT 3360
  204. /**********************************************************************/
  205. /**************  Positioning for the 3812  ****************************/
  206. /**********************************************************************/
  207. #define VERT_HALF(n) ((short)((n+1)>>1)-1)
  208. #define HOR_HALF(n)  ((short)(n>>1))
  209. #define MoveHor(n)  if ((n)!=0) { PMPcont(3); PMPout(1,"\342"); EMITWORD((n)); }
  210. #define MoveVert(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\343"); EMITWORD((n)); }
  211. #endif
  212.  
  213. #ifdef LJ
  214. # ifdef LJ4
  215. #  ifdef LJ4L
  216. #   define  PRINTER       "HP Laserjet 4L"
  217. #  else
  218. #   define  PRINTER       "HP Laserjet 4"
  219. #  endif
  220. # else
  221. #  ifdef LJ2P
  222. #   define  PRINTER       "HP LaserJet IIP"
  223. #  else
  224. #   ifdef LJ2 
  225. #    define  PRINTER       "HP LaserJet 2"
  226. #   else
  227. #    define  PRINTER       "HP LaserJet"
  228. #   endif
  229. #  endif
  230. # endif
  231.  
  232. # ifdef LJ4
  233. #  ifdef LJ4L
  234. int   RESOLUTION = 300;
  235. char *MFMODE     = MFMODE300;
  236. #  else
  237. int   RESOLUTION = 600;
  238. char *MFMODE     = MFMODE600;
  239. #  endif
  240. # else
  241. #  define RESOLUTION 300
  242. # endif
  243. # define  hconvRESOLUTION   RESOLUTION
  244. # define  vconvRESOLUTION   RESOLUTION
  245. # ifdef LJ2
  246. /* the printer limit of the LJ2P is actually 16384x16384, 
  247.   * but to exploit it, one would need lots of memory in the printer
  248.  */
  249. #  define  CHAR_WIDTH_LARGE  200     /* limit for loading into printer font */
  250. #  define  CHAR_HEIGTH_LARGE 255         /* y_offset reaches the same size! */
  251. # else   /* such as LaserJet+, Laserjet II */
  252. #  define  CHAR_WIDTH_LARGE  100     /* limit for loading into printer font */
  253. #  define  CHAR_HEIGTH_LARGE 127         /* y_offset reaches the same size! */
  254. # endif
  255. # define  EMITFILE_EXTENSION  ".lj"       /* default extension of emit file */
  256. # ifndef MAX_FONTS_PER_PAGE
  257. #  define  MAX_FONTS_PER_PAGE 16        /* maximum number of fonts per page */
  258. # endif
  259. # define  HANDLE_MAX_FONTS  255      /* max nr of fonts handled (rasterfont) */
  260. # define  FONTS_DOWNLOADABLE 32    /* max nr of fonts that can be downloaded */
  261. # define  MAXFONTSTORAGE (395l*1024l)                /* standard user memory */
  262. # define  EMITC(c)       putc(c,outfp)          /* output a single character */
  263. # define  EMITL(l,d)     EMITB(l,d)                  /* EMIT-logical = EMITB */
  264. # ifdef LJ4
  265. #  define  XDEFAULTOFF   RESOLUTION 
  266. #  define  YDEFAULTOFF   RESOLUTION
  267. # else
  268. #  define  XDEFAULTOFF   RESOLUTION-54   /*x default offset on page 1in (LJ2)*/
  269. #  define  YDEFAULTOFF   RESOLUTION+9      /* y default offset on page 1inch */
  270. # endif
  271. # define  max(x,y)       if ((y)>(x)) x = y
  272. # ifndef vms
  273. #  define  INT_ASCII(b,i) \
  274.    if (i == 0) b[0] = '\0'; else sprintf((char *)b,"%hd",i)
  275. # else
  276. #  define  INT_ASCII(b,i) \
  277.    if (i == 0) b[0] = '\0'; else sprintf((char *)b,"%d",i)
  278. # endif
  279. #endif
  280. #ifdef SEVENBIT
  281. #define VIS   33
  282. #define VIS2  (VIS+32)
  283. unsigned char
  284. VisChar(c)
  285. unsigned char   c;
  286. {
  287.     c &= 0xff;
  288.     if (c < VIS)
  289.         return ((unsigned char)(160 + c));
  290.     if (c < 128)
  291.         return (c);
  292.     if (c < (255 - VIS2))
  293.         return ((unsigned char)(VIS2 + c));
  294.     return (255);
  295. }
  296. #else
  297. #define VisChar(c) (unsigned char)(c)
  298. #endif
  299.  
  300.  
  301. /**********************************************************************/
  302. /***********************  external definitions  ***********************/
  303. /**********************************************************************/
  304.  
  305. #ifndef _AMIGA
  306. #ifndef unix
  307. #if !defined (__amiga__) && !defined (__gnuc__)
  308. long    access();
  309. #endif
  310. FILE   *BOPENCMD();
  311. void    exit();
  312. int     fclose();
  313. int     fprintf();
  314. int     fseek();
  315. char   *index();
  316. int     printf();
  317. int     sscanf();
  318. int     strcmp();
  319. char   *strcpy();
  320. #ifdef MSC5
  321. unsigned int strlen();
  322. #endif
  323. void    free();
  324. void    setbuf();
  325. #endif
  326.  
  327. #ifdef MSDOS
  328. int     intdos();
  329. #endif
  330. #endif
  331.  
  332.  
  333. #ifndef USEPXL
  334. /* interface to gf.c */
  335. extern FILE *gfin;
  336. extern int checksum;
  337. extern long4 tfm_wd[], char_pointer[];
  338. extern char char_exists[];
  339. extern int num_cols, num_rows, num_bytes, x_offset, y_offset;
  340. extern unsigned char bits[];
  341. extern int gf_font_max_m, gf_font_max_n, gf_font_min_n;
  342. extern int gettochar();
  343. extern void readbits();
  344. extern void readpost();
  345. extern void seekpost();
  346. extern int seekchar();
  347. #endif
  348.  
  349.  
  350. /**********************************************************************/
  351. /*************************  Global Procedures  ************************/
  352. /**********************************************************************/
  353. /* Note: Global procedures are declared here in alphabetical order, with
  354.    those which do not return values typed "void".  Their bodies occur in
  355.    alphabetical order following the main() procedure.  The names are
  356.    kept unique in the first 6 characters for portability. */
  357. double  ActualFactor();
  358. void    AllDone();
  359. #ifdef  MSDOS
  360. void    AssureBinary();  /* DOS and Microsoft C dependent !!! */
  361. #endif
  362. void    CopyFile();
  363. void    CopyHPFile();
  364. void    DecodeArgs();
  365. void    DoBop();
  366. long4    DoConv();
  367. void    DoSpecial();
  368. void    EmitChar();
  369. void    Fatal();
  370. void    FindPostAmblePtr();
  371. void    FormFeed();
  372. void    GetBytes();
  373. void    GetFontDef();
  374. char    *GetKeyStr();
  375. bool    GetKeyVal();
  376. bool    IsSame();
  377. void    lcase();
  378. void    LoadAChar();
  379. long4    NoSignExtend();
  380. /* see cautionary note in code, re arithmetic vs logical shifts */
  381. void    OpenFontFile();
  382. long4    PixRound();
  383. void    PkRaster();
  384. void    PutWord();
  385. void    RasterLine();
  386. void    RasterChar();
  387. void    ReadFontDef();
  388. void    ReadPostAmble();
  389. void    SetChar();
  390. void    SetFntNum();
  391. void    SetPosn();
  392. void    SetRule();
  393. void    SetString();
  394. long4    SignExtend();
  395. /* see cautionary note in code, re arithmetic vs logical shifts */
  396. void    SkipFontDef();
  397. void    Warning();
  398. unsigned char   skip_specials() ;
  399.  
  400. #ifdef IBM3812
  401. void    PMPout();
  402. void    PMPoutC();
  403. #endif
  404.  
  405. /**********************************************************************/
  406. /***********************  Font Data Structures  ***********************/
  407. /**********************************************************************/
  408.  
  409. struct char_entry {             /* character entry */
  410. #ifdef USEPXL
  411.     unsigned short  width, height;      /* width and height in pixels */
  412.     short   xOffset, yOffset, yyOffset; /* x offset and y offset in pixels*/
  413. #endif
  414.     struct {
  415.         bool isloaded;
  416.         union {
  417.             long4    fileOffset;
  418.             long4    *pixptr;
  419.         } address;
  420.     } where;
  421.     long4    tfmw;             /* TFM width                 */
  422.     long4    cw;               /* character width in pixels */
  423.     unsigned char   flag_byte;          /* for PK-files    */
  424.     unsigned char   charsize;
  425. };
  426. struct font_entry {    /* font entry */
  427.     long4    k, c, s, d;
  428.     int     a, l;
  429.     char n[STRSIZE];          /* FNT_DEF command parameters                */
  430.     long4    font_mag;         /* computed from FNT_DEF s and d parameters  */
  431.     /*char psname[STRSIZE];*/ /* PostScript name of the font               */
  432.     char    name[STRSIZE];    /* full name of PXL file                     */
  433.     FILE * font_file_id;      /* file identifier (NO_FILE if none)         */
  434. #ifdef USEPXL
  435.     long4    magnification;    /* magnification read from PXL file          */
  436.     long4    designsize;       /* design size read from PXL file            */
  437. #endif
  438.     struct char_entry ch[NFNTCHARS];   /* character information            */
  439.     struct font_entry *next;
  440.     unsigned short ncdl;      /* #of different chars actually downloaded   */
  441.     unsigned short plusid;    /* Font id in Printer                        */
  442.     bool used_on_this_page;
  443. #ifdef LJ_RESIDENT_FONTS
  444.     bool resident_p;          /* is font resident in printer?              */
  445.     char symbol_set[40];      /* symbol set value (resident fonts)         */
  446.     unsigned short resid;     /* typeface id (resident fonts)              */
  447.     unsigned spacing;         /* 0=monospace, 1=variable (resident fonts)  */
  448.     unsigned style;           /* upright/italic/... (resident fonts)       */
  449.     int weight;               /* regular/bold/... (resident fonts)         */
  450.     double pitch;             /* chars per inch (monospaced resident fonts)*/
  451. #endif
  452.     enum PxlId {
  453.         id1001, id1002, pk89    } id;
  454. #ifdef LJ
  455.     unsigned short max_width, max_height, max_yoff;
  456. #endif
  457. };
  458.  
  459.  
  460. struct pixel_list {
  461.     FILE *pixel_file_id;    /* file identifier  */
  462.     int     use_count;      /* count of "opens" */
  463. };
  464. /**********************************************************************/
  465. /*************************  Global Variables  *************************/
  466. /**********************************************************************/
  467. long    FirstPage  = -1000000;  /* first page to print (uses count0)   */
  468. long    LastPage   = 1000000;   /* last page to print                  */
  469. long    PrintPages = 1000000;   /* nr of pages to print                */
  470. bool    FirstPageSpecified = _FALSE;
  471. bool    LastPageSpecified = _FALSE;
  472. char    G_progname[STRSIZE];    /* program name                        */
  473. char    filename[STRSIZE];      /* DVI file name                       */
  474. char    rootname[STRSIZE];      /* DVI filename without extension      */
  475. char    *HeaderFileName = "";   /* file name & path of Headerfile      */
  476. char    *EmitFileName = "";     /* file name & path for output         */
  477. #ifdef IBM3812
  478. bool    FirstAlternate = _FALSE; /* first page from alternate casette ? */
  479. #endif
  480. bool    Reverse = _FALSE;        /* process DVI pages in reverse order? */
  481. bool    Landscape = _FALSE;      /* print document in ladscape mode     */
  482. bool    ResetPrinter = _TRUE;    /* reset printer at the begin of the job*/
  483. bool    DoublePage = _FALSE;     /* print on both sides of a paper      */
  484. bool    PrintSecondPart = _TRUE; /* print First Part when DoublePage    */
  485. bool    PrintFirstPart = _TRUE;  /* print Second Part when DoublePage   */
  486. bool    PrintEmptyPages = _TRUE; /* print Empty pages in DoublePage mode*/
  487. short   PageParity = 1;
  488. #ifdef MAKETEXPK
  489. #ifdef NOMAKETEXPK
  490. #define MAKETEXPK_BY_DEFAULT_VALUE 0
  491. #else
  492. #define MAKETEXPK_BY_DEFAULT_VALUE 1
  493. #endif
  494. bool    makeTexPK = MAKETEXPK_BY_DEFAULT_VALUE;
  495. #endif
  496.  
  497. #ifdef LJ
  498. #ifdef LJ2P
  499. int     DuplexMode = 0;
  500. #endif
  501. #ifdef LJ4
  502. bool    econoMode = _FALSE;
  503. #endif
  504. bool    PrintTestPage = _FALSE; /* print testpage with pagecounter after job */
  505. unsigned short pagesize = 0;    /* page size value                      */
  506. unsigned short pgsiz_dots = 0;  /* page size in dots (for rule-clipping)*/
  507. #endif
  508.  
  509.  
  510. #ifndef vms
  511. short   G_errenc = 0;           /* has an error been encountered?      */
  512. #else
  513. long4    G_errenc = SS$_NORMAL;  /* has an error been encountered?      */
  514. #endif
  515. bool    G_header = _FALSE;      /* copy header file to output?         */
  516. bool    G_quiet = _FALSE;       /* for quiet operation                 */
  517. bool    G_noverbatim = _TRUE;   /* inform user about pxl-files used    */
  518. bool    G_nowarn = _FALSE;      /* don't print out warnings            */
  519. short   x_origin;               /* x-origin in dots                    */
  520. short   y_origin;               /* y-origin in dots                    */
  521. short   x_goffset;              /* global x-offset in dots             */
  522. short   y_goffset;              /* global y-offset in dots             */
  523. unsigned short ncopies = 1;     /* number of copies to print           */
  524. long4    hconv, vconv;           /* converts DVI units to pixels        */
  525. long4    den;                    /* denominator specified in preamble   */
  526. long4    num;                    /* numerator specified in preamble     */
  527. long4    h;                      /* current horizontal position         */
  528. long4    hh = 0;                 /* current h on device                 */
  529. long4    v;                      /* current vertical position           */
  530. long4    vv = 0;                 /* current v on device                 */
  531. long4    mag;                    /* magnification specified in preamble */
  532. long    usermag = 0;            /* user specified magnification        */
  533. int     ndone = 0;              /* number of pages converted           */
  534. int     nopen = 0;              /* number of open PXL files            */
  535. #ifdef vms
  536. int    kk;            /* loop variable for EMITB           */
  537. #endif
  538. FILE  *outfp = NULL;            /* output file                         */
  539. FILE  *pxlfp;                   /* PXL file pointer                    */
  540. FILE  *dvifp  = NULL;           /* DVI file pointer                    */
  541. struct font_entry *prevfont = NULL; /* font_entry pointer previous font*/
  542. struct font_entry *fontptr;     /* font_entry pointer                  */
  543. struct font_entry *hfontptr = NULL; /* font_entry pointer              */
  544. struct font_entry *pfontptr = NULL; /* previous font_entry pointer     */
  545. struct pixel_list pixel_files[MAXOPEN+1]; /* list of open PXL files    */
  546. long4    postambleptr;           /* Pointer to the postamble            */
  547. long4    ppagep;                 /* previous page pointer               */
  548. static int      last_ry = UNKNOWN;      /* last y-position on page     */
  549. static int      last_rx = UNKNOWN;      /* last x-position on page     */
  550. long4   StartPrintPages;         /* notpad for double paged output      */
  551. int    WouldPrint    = 0;
  552. bool   ZeroPage = _FALSE;       /* Document starts with a Zero Page    */
  553. bool   EvenPage = _FALSE;       /* Document starts with an even Page   */
  554. long4   LastPtobePrinted = 0;
  555. int    G_ncdl = 0;
  556.  
  557. long4    allocated_storage = 0; /* size of mallocated storage (statistics) */
  558. long4    power[32] ;
  559. long4    gpower[33] ;
  560.  
  561.  
  562. #ifdef DEBUG
  563. int Debug = 0;
  564. #endif
  565.  
  566. #ifdef LJ
  567. int   fonts_used_on_this_page = MAX_FONTS_PER_PAGE+1;
  568. char  rasterfont[HANDLE_MAX_FONTS];
  569.     /* raster if fonts/page>MAX_FONTS_PER_PAGE*/
  570. #ifdef LJ_RESIDENT_FONTS
  571. unsigned resident_count = 0;
  572. #ifndef KPATHSEA
  573. char *TFMpath = DEFAULT_TFM_PATH;
  574. #endif
  575. #endif
  576. #endif
  577.  
  578. long4     used_fontstorage = 0;
  579.  
  580. #ifdef IBM3812
  581. char    PMPformat[20];
  582. char    CharString[CHARSTRINGMAX];
  583. unsigned int CharStringPos = 0;
  584. #define CharStringOut \
  585.     if (CharStringPos>0) { \
  586.         PMPcont(CharStringPos+1);\
  587.         PMPoutC((unsigned char)CharStringPos);\
  588.         PMPout(CharStringPos, CharString); \
  589.         CharStringPos=0; }
  590. #endif
  591.  
  592. #ifdef TIMING
  593. /************************timing stuff*********************/
  594. #ifdef BSD_TIME_CALLS
  595. #ifndef vms
  596. #include <sys/timeb.h>
  597. #else
  598. #include <timeb.h>
  599. #endif
  600. struct timeb timebuffer;
  601. double  start_time;
  602. #else
  603. #include <sys/time.h>
  604. struct timeval Tp;
  605. double  start_time;
  606. #endif
  607. #endif
  608.  
  609.  
  610.  
  611. /**********************************************************************/
  612. /*******************************  main  *******************************/
  613. /**********************************************************************/
  614. int
  615. main(argc, argv)
  616. int     argc;
  617. char    *argv[];
  618. {
  619.     struct stack_entry {  /* stack entry */
  620.         long4    h, v, w, x, y, z;  /* what's on stack */
  621.     };
  622.     short   command;          /* current command                         */
  623.     long4    count[10];        /* the 10 counters at begining of each page*/
  624.     long4    cpagep = 0;       /* current page pointer                    */
  625.     bool Emitting = _FALSE;   /* outputting typsetting instructions?     */
  626.     int     i;                /* command parameter; loop index           */
  627.     int     k;                /* temporary parameter                     */
  628.     char    n[STRSIZE];       /* command parameter                       */
  629.     int     PassNo = 0;       /* which pass over the DVI page are we on? */
  630.     bool SkipMode = _FALSE;   /* in skip mode flag                       */
  631.     int     sp = 0;           /* stack pointer                           */
  632.     struct stack_entry stack[STACK_SIZE];  /* stack                      */
  633.     char    SpecialStr[STRSIZE]; /* "\special" strings                   */
  634.     long4    val, val2;        /* temporarys to hold command information  */
  635.     long4    w = 0;            /* current horizontal spacing              */
  636.     long4    x = 0;            /* current horizontal spacing              */
  637.     long4    y = 0;            /* current vertical spacing                */
  638.     long4    z = 0;            /* current vertical spacing                */
  639.  
  640.  
  641. #ifdef vms
  642.     extern noshare int errno;
  643.     extern noshare char *sys_errlist[];
  644. #else
  645.     extern  char *sys_errlist[];
  646.     extern  int     errno;
  647. #endif
  648.  
  649.     x_origin = XDEFAULTOFF; /* x-origin in dots                    */
  650.     y_origin = YDEFAULTOFF; /* y-origin in dots                    */
  651.  
  652.     setbuf(stderr, NULL);
  653.     (void) strcpy(G_progname, argv[0]);
  654. #ifdef KPATHSEA
  655.     kpse_set_progname (argv[0]);
  656. #endif
  657.     DecodeArgs( argc, argv );
  658.  
  659. #ifdef KPATHSEA
  660.     kpse_init_prog ("DVILJ", RESOLUTION, MFMODE, makeTexPK, "cmr10");
  661. #endif
  662.  
  663.     power [ 0 ] = 1 ;
  664.     for ( i = 1 ; i <= 31 ; i ++)
  665.         power [ i ] = power [ i - 1 ] << 1 ;
  666.     gpower[0] = 0l ;
  667.     for ( i = 1 ; i <= 32 ; i ++)
  668.         gpower[i] = gpower[i - 1] + power[i - 1] ;
  669.  
  670.     if ((i = (int) NoSignExtend(dvifp, 1)) != PRE)  {
  671.         Fatal(
  672.         "%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n",
  673.                 G_progname);
  674.     }
  675.     i = (int) SignExtend(dvifp, 1);
  676.     if (i != DVIFORMAT)  {
  677.         Fatal( "%s: DVI format = %d, can only process DVI format %d files\n\n",
  678.                 G_progname, i, DVIFORMAT);
  679.     }
  680.  
  681.     if (*EmitFileName == '-')
  682.         outfp = stdout;
  683.     else
  684.         if ((outfp = fopen(EmitFileName, WRITE_BINARY)) == NULL)
  685.         Fatal("opening output file: fopen(%s) : %s",
  686.             EmitFileName,sys_errlist[errno]);
  687.  
  688. #ifdef MSDOS
  689.     AssureBinary(outfp);
  690. #endif
  691.  
  692. #ifdef TIMING
  693. #ifdef BSD_TIME_CALLS
  694.     ftime(&timebuffer);
  695.     start_time = timebuffer.time + (float)(timebuffer.millitm) / 1000.0;
  696. #else
  697.     gettimeofday(&Tp, NULL);
  698.     start_time = Tp.tv_sec + ((float)(Tp.tv_usec))/ 1000000.0;
  699. #endif
  700. #endif
  701.  
  702.     /* it is important that these be the very first things output !!! */
  703.     if ( G_header )
  704.         CopyFile( HeaderFileName );
  705.  
  706.     /*****************************/
  707.     /*for( i0=0; i0<nif; i0++ )  */    /* copy all included files */
  708.     /*    CopyFile( Ifile[i0] ); */
  709.     /*****************************/
  710.  
  711. #ifdef IBM3812
  712.     PMPout(3, "\307\310\366");          /* unload all fonts and macros */
  713.     EMITWORD(MAX_PAGE_WIDTH);
  714.     EMITWORD(MAX_PAGE_HEIGHT);
  715.     if (Landscape)
  716.         PMPout(2, "\322\1");
  717. #endif
  718. #ifdef LJ
  719.     if (ResetPrinter)
  720.       EMIT(outfp, "\033E");
  721. #ifdef LJ4
  722.     EMIT(outfp, "\033%%-12345X@PJL SET RESOLUTION=%u\012", RESOLUTION);
  723.     EMIT(outfp, "@PJL SET PAGEPROTECT=OFF\012");
  724.     EMIT(outfp, "@PJL ENTER LANGUAGE=PCL\012");
  725.     EMIT(outfp, "\033&u%uD\033*t%uR", RESOLUTION, RESOLUTION);
  726.     if (econoMode)
  727.       EMIT(outfp, "\033*v1T");
  728. #endif
  729. #ifdef LJ2P
  730.     if (DuplexMode) 
  731.       EMIT(outfp, "\033&l%dH", DuplexMode); 
  732. #endif
  733.     if (Landscape)
  734.       EMIT(outfp, "\033&l1O\033*rF");
  735.     if (pagesize>0)
  736. #ifndef vms
  737.       EMIT(outfp, "\033&l%hdaE\033&aL", pagesize);
  738. #else
  739.       EMIT(outfp, "\033&l%daE\033&aL", pagesize);
  740. #endif
  741.     else
  742.       EMIT(outfp, "\033&lE\033&aL");
  743.  
  744.     if (ncopies>1)
  745. #ifndef vms
  746.       EMIT(outfp, "\033&l%hdX", ncopies);
  747. #else
  748.       EMIT(outfp, "\033&l%dX", ncopies);
  749. #endif
  750. #endif
  751.     if (DoublePage) {
  752.          StartPrintPages = PrintPages;
  753. #ifdef IBM3812
  754.          Reverse = (bool)!Reverse; /* perverse and strange */
  755. #endif
  756.  
  757.     }
  758.     if (Reverse) {
  759. #ifdef DEBUG
  760.         if (Debug)
  761.               fprintf(stderr, "reverse\n");
  762. #endif
  763.         ReadPostAmble(_TRUE);
  764.         fseek(dvifp, ppagep, 0);
  765.     } else {
  766.         ReadPostAmble(_TRUE);
  767.         fseek(dvifp,  14l, 0);
  768.         k = (int) NoSignExtend(dvifp, 1);
  769.         GetBytes(dvifp, n, k);
  770.     }
  771.     PassNo = 0;
  772.  
  773.     while (_TRUE)  {
  774.         command = (short) NoSignExtend(dvifp, 1)   ;
  775. #ifdef DEBUG
  776.         if (Debug)
  777.                fprintf(stderr,"CMD:\t%d\n", command);
  778. #endif
  779.         switch (command)  {
  780.         case SET1:
  781.         case SET2:
  782.         case SET3:
  783.         case SET4:
  784.             val = NoSignExtend(dvifp, (int) command - SET1 + 1);
  785.             if (!SkipMode)
  786.                 SetChar(val, command, PassNo, _TRUE,_FALSE);
  787.             break;
  788.         case SET_RULE:
  789.             val = NoSignExtend(dvifp, 4);
  790.             val2 = NoSignExtend(dvifp, 4);
  791.             if (Emitting)
  792.                 SetRule(val, val2, 1);
  793.             break;
  794.         case PUT1:
  795.         case PUT2:
  796.         case PUT3:
  797.         case PUT4:
  798.             val = NoSignExtend(dvifp, (int) command - PUT1 + 1);
  799.             if (!SkipMode)
  800.                 SetChar(val, command, PassNo, _TRUE,_FALSE);
  801.             break;
  802.         case PUT_RULE:
  803.             val = NoSignExtend(dvifp, 4);
  804.             val2 = NoSignExtend(dvifp, 4);
  805.             if (Emitting)
  806.                 SetRule(val, val2, 0);
  807.             break;
  808.         case NOP:
  809.             break;
  810.         case BOP:
  811.             cpagep = ftell(dvifp) - 1;
  812.             for (i = 0; i <= 9; i++)
  813.                 count[i] = NoSignExtend(dvifp, 4);
  814.             ppagep = NoSignExtend(dvifp, 4);
  815.             h = v = w = x = y = z = 0;
  816.             hh = vv = 0;
  817.             sp = 0;
  818.             fontptr = NULL;
  819.             prevfont = NULL;
  820.             DoBop();
  821. /*
  822. fprintf(stderr,"skimode %d, count %d, F %d, L %d\n",
  823.     (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified);
  824. */
  825.             SkipMode = (bool) ((FirstPageSpecified && count[0] < FirstPage) || 
  826.                                               (LastPageSpecified && count[0] > LastPage ));
  827. /*
  828. fprintf(stderr,"skimode %d, count %d, F %d, L %d\n",
  829.     (int)SkipMode,(int)count[0],(int)FirstPageSpecified,(int)LastPageSpecified);
  830. */
  831.  
  832.             if (DoublePage && !SkipMode) {
  833.                if (PassNo == 0) {
  834.                   LastPtobePrinted=count[0];
  835.                   if (!Reverse && (WouldPrint == 0)) {
  836.                       if (count[0] == 0l) {
  837.                          ZeroPage = _TRUE;
  838.                          EvenPage = _FALSE;
  839.                       }
  840.                       else {
  841.                          EvenPage = (bool) ( (count[0]<0? labs(count[0])+1: count[0]) %2 == 0);
  842.  
  843.                          if (PrintEmptyPages && EvenPage && PageParity==1) {
  844.                            WouldPrint ++;
  845.                if (PrintFirstPart) {
  846.                  qfprintf(stderr,"[EvenPage] ");
  847.                  FormFeed();
  848.                }
  849.                          }
  850.                       }
  851.                   }
  852.                   WouldPrint ++;
  853. /*
  854.     fprintf(stderr, "doublepage %d, page parity = %d, 1=%d 2=%d, Reverse %d, WouldPrint %d, fpZ %d\n",
  855.         (int)DoublePage, (int)PageParity,(int)PrintFirstPart,(int)PrintSecondPart,
  856.         (int)Reverse, (int)WouldPrint, (int)ZeroPage);
  857. */
  858.         }
  859.            if (!PrintFirstPart && PageParity==1) { 
  860.          if (count[0]==0l) {
  861.            ZeroPage = _TRUE;
  862.            EvenPage = _FALSE;
  863.          }
  864.          SkipMode = _TRUE;
  865.            }
  866.                else { 
  867. /*
  868. fprintf(stderr,"FirstPart\n count %d, mod %d, pp %d\n",(int)count[0],(int)count[0]%2,PageParity);
  869. */
  870.          SkipMode = (bool)(PageParity != (short)(
  871.                              (count[0]<0?  labs(count[0])+1: count[0])%2));
  872.          if (count[0]==0l) SkipMode=(bool)!SkipMode;
  873.            }
  874.  
  875.             }
  876.             Emitting = (bool)((PassNo != 0) && !SkipMode);
  877. /*
  878. fprintf(stderr,"Emitting= %d, PassNo=%d, SkipMode = %d\n",(int)Emitting,(int)PassNo,(int)SkipMode);
  879. */
  880.             if ( !SkipMode ) {
  881.                 if ( PassNo == 0)
  882.                     qfprintf(stderr, "[%ld", (long)count[0]);
  883.             }
  884.             break;
  885.         case EOP:
  886.             if ( !SkipMode ) {
  887.                 if ( PassNo == 0 ) {
  888.                     /* start second pass on current page */
  889.                     fseek(dvifp, cpagep, 0);
  890.                     PassNo = 1;
  891. #ifdef DEBUG
  892.             if (Debug)
  893.                       fprintf(stderr,"\nStarting second pass\n");
  894. #endif
  895.  
  896.                 } else {
  897.                    /* end of second pass, and of page processing */
  898.  
  899.                     last_ry = UNKNOWN;
  900.                     FormFeed();
  901.                     ++ndone;
  902.  
  903.                     qfprintf(stderr, "] ");
  904.                     if ( (ndone % 10) == 0 )
  905.                           qfprintf(stderr, "\n");
  906.  
  907.                     if (DoublePage) --PrintPages;
  908.                     if (--PrintPages < 1) AllDone(_TRUE);
  909.                     PassNo = 0;
  910.                 }
  911.             } else
  912.                 PassNo = 0;
  913.  
  914.             if ( PassNo == 0 && Reverse ) {
  915.                 if ( ppagep > 0 )
  916.                     fseek(dvifp, ppagep, 0);
  917.                 else {
  918.                    if (DoublePage && !SkipMode)
  919.                      ZeroPage = (bool)(count[0]==0l);
  920.  
  921.                    if (ZeroPage)
  922.                      EvenPage = _FALSE;
  923.                    else
  924.                      EvenPage = (bool) ((int)LastPtobePrinted%2 == 0);
  925.  
  926.                    AllDone(_FALSE);
  927.                 }
  928.             }
  929.             break;
  930.         case PUSH:
  931.             if (sp >= STACK_SIZE)
  932.                 Fatal("stack overflow");
  933.             stack[sp].h = h;
  934.             stack[sp].v = v;
  935.             stack[sp].w = w;
  936.             stack[sp].x = x;
  937.             stack[sp].y = y;
  938.             stack[sp].z = z;
  939.             sp++;
  940.             break;
  941.         case POP:
  942.             --sp;
  943.             if (sp < 0)
  944.                 Fatal("stack underflow");
  945.             h = stack[sp].h;
  946.             v = stack[sp].v;
  947.             w = stack[sp].w;
  948.             x = stack[sp].x;
  949.             y = stack[sp].y;
  950.             z = stack[sp].z;
  951.             break;
  952.         case RIGHT1:
  953.         case RIGHT2:
  954.         case RIGHT3:
  955.         case RIGHT4:
  956.             val = SignExtend(dvifp, (int) command - RIGHT1 + 1);
  957.             if (Emitting)
  958.                 MoveOver(val);
  959.             break;
  960.         case W0:
  961.             if (Emitting)
  962.                 MoveOver(w);
  963.             break;
  964.         case W1:
  965.         case W2:
  966.         case W3:
  967.         case W4:
  968.             w = SignExtend(dvifp, (int)command - W1 + 1);
  969.             if (Emitting)
  970.                 MoveOver(w);
  971.             break;
  972.         case X0:
  973.             if (Emitting)
  974.                 MoveOver(x);
  975.             break;
  976.         case X1:
  977.         case X2:
  978.         case X3:
  979.         case X4:
  980.             x = SignExtend(dvifp, (int)command - X1 + 1);
  981.             if (Emitting)
  982.                 MoveOver(x);
  983.             break;
  984.         case DOWN1:
  985.         case DOWN2:
  986.         case DOWN3:
  987.         case DOWN4:
  988.             val = SignExtend(dvifp, (int)command - DOWN1 + 1);
  989.             if (Emitting)
  990.                 MoveDown(val);
  991.             break;
  992.         case Y0:
  993.             if (Emitting)
  994.                 MoveDown(y);
  995.             break;
  996.         case Y1:
  997.         case Y2:
  998.         case Y3:
  999.         case Y4:
  1000.             y = SignExtend(dvifp, (int)command - Y1 + 1);
  1001.             if (Emitting)
  1002.                 MoveDown(y);
  1003.             break;
  1004.         case Z0:
  1005.             if (Emitting)
  1006.                 MoveDown(z);
  1007.             break;
  1008.         case Z1:
  1009.         case Z2:
  1010.         case Z3:
  1011.         case Z4:
  1012.             z = SignExtend(dvifp, (int)command - Z1 + 1);
  1013.             if (Emitting)
  1014.                 MoveDown(z);
  1015.             break;
  1016.         case FNT1:
  1017.         case FNT2:
  1018.         case FNT3:
  1019.         case FNT4:
  1020.             if (!SkipMode) {
  1021.                 SetFntNum(NoSignExtend(dvifp, (int)command -FNT1 +1),Emitting);
  1022.             }
  1023.             break;
  1024.         case XXX1:
  1025.         case XXX2:
  1026.         case XXX3:
  1027.         case XXX4:
  1028.             k = (int) NoSignExtend(dvifp, (int)command - XXX1 + 1);
  1029.             GetBytes(dvifp, SpecialStr, k);
  1030.             if (Emitting)
  1031.                 DoSpecial(SpecialStr, k);
  1032.             break;
  1033.         case FNT_DEF1:
  1034.         case FNT_DEF2:
  1035.         case FNT_DEF3:
  1036.         case FNT_DEF4:
  1037.             k = (int) NoSignExtend(dvifp, (int)command - FNT_DEF1 + 1);
  1038.             SkipFontDef();    /* SkipFontDef(k); */
  1039.             break;
  1040.         case PRE:
  1041.             Fatal("PRE occurs within file");
  1042.             break;
  1043.         case POST:
  1044.             AllDone(_FALSE);
  1045.             PassNo = 0;
  1046.             break;
  1047.         case POST_POST:
  1048.             Fatal("POST_POST with no preceding POST");
  1049.             break;
  1050.         default:
  1051.             if (command >= FONT_00 && command <= FONT_63) {
  1052.                 if (!SkipMode)
  1053.                     SetFntNum((long4) command - FONT_00, Emitting);
  1054.             } else if (command >= SETC_000 && command <= SETC_127) {
  1055.                 if (!SkipMode) {
  1056.                     SetString(command, PassNo);
  1057.                 }
  1058.             } else
  1059.                 Fatal("%d is an undefined command", command);
  1060.             break;
  1061.         }
  1062.     } /* while _TRUE */
  1063. }
  1064.  
  1065.  
  1066. /*-->ActualFactor*/
  1067. /**********************************************************************/
  1068. /**************************  ActualFactor  ****************************/
  1069. /**********************************************************************/
  1070. double  /* compute the actual size factor given the approximation */
  1071. ActualFactor(unmodsize)
  1072. long4    unmodsize;                 /* actually factor * 1000 */
  1073. {
  1074.     double  realsize;     /* the actual magnification factor */
  1075.     realsize = (double)unmodsize / 1000.0;
  1076.     if (abs((int)(unmodsize - 1095l))<2)
  1077.         realsize = 1.095445115; /*stephalf*/
  1078.     else if (abs((int)(unmodsize - 1315l))<2)
  1079.         realsize = 1.31453414; /*stepihalf*/
  1080.     else if (abs((int)(unmodsize - 1577l))<2)
  1081.         realsize = 1.57744097; /*stepiihalf*/
  1082.     else if (abs((int)(unmodsize - 1893l))<2)
  1083.         realsize = 1.89292916; /*stepiiihalf*/
  1084.     else if (abs((int)(unmodsize - 2074l))<2)
  1085.         realsize = 2.0736;   /*stepiv*/
  1086.     else if (abs((int)(unmodsize - 2488l))<2)
  1087.         realsize = 2.48832;  /*stepv*/
  1088.     else if (abs((int)(unmodsize - 2986l))<2)
  1089.         realsize = 2.985984; /*stepvi*/
  1090.     /* the remaining magnification steps are represented with sufficient
  1091.        accuracy already */
  1092.     return(realsize);
  1093. }
  1094.  
  1095.  
  1096. /*-->AllDone*/
  1097. /**********************************************************************/
  1098. /****************************** AllDone  ******************************/
  1099. /**********************************************************************/
  1100. void
  1101. AllDone(PFlag)
  1102. bool PFlag;
  1103. {
  1104. #ifdef TIMING
  1105.     double  time;
  1106. #endif
  1107.  
  1108.     if (DoublePage && (PageParity==1)) { /* Shall we go around again?*/
  1109.         int k;
  1110.         char    n[STRSIZE];
  1111.  
  1112.         if (PrintEmptyPages && EvenPage && Reverse && PrintFirstPart) {
  1113.             WouldPrint ++;
  1114.             qfprintf(stderr,"[EvenPage] ");
  1115.             FormFeed();
  1116.         }
  1117. #ifdef LJ
  1118.         Reverse = (bool)!Reverse;
  1119. #endif
  1120.         if (Reverse) {
  1121.             if (!PFlag) {
  1122.                fseek (dvifp, postambleptr, 0);
  1123.                (void) NoSignExtend(dvifp, 1);
  1124.                ppagep = NoSignExtend(dvifp, 4);
  1125.             }
  1126.             fseek(dvifp, ppagep, 0);
  1127.         } else {
  1128.             fseek(dvifp,  14l, 0);
  1129.         k = (int) NoSignExtend(dvifp, 1);
  1130.         GetBytes(dvifp, n, k);
  1131.         }
  1132.  
  1133.     if (PrintSecondPart) {
  1134.       if (PrintFirstPart) {
  1135.         qfprintf(stderr,"\n----------------------starting second pass\n");
  1136. #ifdef LJ
  1137.         EMIT(outfp, "\033&l2H"); /* Manual Feed */
  1138. #endif
  1139. #ifdef IBM3812
  1140.         PMPout(6,"\326\001\305\300\326\252");
  1141.         /* set display; ring bell; stop; clear display */
  1142.         PMPflush;
  1143. #endif
  1144.       }
  1145.  
  1146.       if (PrintEmptyPages && Reverse) {
  1147.         if (ZeroPage) WouldPrint++;
  1148.         if ((WouldPrint%2) == 1) {
  1149.           qfprintf(stderr,"[Padding] ");
  1150.           FormFeed();
  1151.         }
  1152.       }
  1153.       WouldPrint = 0;
  1154.       if (PrintEmptyPages && !Reverse && ZeroPage) {
  1155.         WouldPrint++;
  1156.         qfprintf(stderr,"[ZeroPage] ");
  1157.         FormFeed();
  1158.       }
  1159.       PageParity = 0;
  1160.       PrintPages = StartPrintPages;
  1161.       return;
  1162.     }
  1163.     }
  1164.  
  1165.     if (EvenPage && DoublePage && !Reverse) WouldPrint++;
  1166.  
  1167.     if (PrintEmptyPages && DoublePage && PrintSecondPart) {
  1168.         if (Reverse) {
  1169.       if (ZeroPage) {
  1170.             WouldPrint ++;
  1171.             qfprintf(stderr,"[ZeroPage] ");
  1172.             FormFeed();
  1173.       }
  1174.         }
  1175.         else if ((WouldPrint%2) != 0) {
  1176.             qfprintf(stderr,"[Padding] ");
  1177.             FormFeed();
  1178.         }
  1179.     }
  1180.  
  1181. #ifdef IBM3812
  1182.     PMPout(10, "\373\010PMP.init");  /* re-init printer  */
  1183.     PMPflush;
  1184.  
  1185.     if (used_fontstorage > MAXFONTSTORAGE) {
  1186.         Warning("\n\7used font_storage of %s: %ld Bytes (of %ld)\7",
  1187.             PRINTER, (long)used_fontstorage, (long)MAXFONTSTORAGE);
  1188.         Warning("Try to format file in separate runs!");
  1189.     } else
  1190.         qfprintf(stderr,
  1191.            "\nAll done, used font_storage of %s: %ld Bytes (of %ld)",
  1192.              PRINTER, (long)used_fontstorage, (long)MAXFONTSTORAGE);
  1193. #endif
  1194. #ifdef LJ
  1195.     qfprintf(stderr, "\nAll done, used font_storage of %s: %ld Bytes",
  1196.              PRINTER, (long)used_fontstorage);
  1197. #ifdef LJ_RESIDENT_FONTS
  1198.     qfprintf(stderr, " + %d resident font%s", resident_count,
  1199.              resident_count == 1 ? "" : "s");
  1200. #endif
  1201.     EMIT(outfp, "\033E");
  1202. #ifdef LJ4
  1203.     EMIT(outfp, "\033%%-12345X");   /* what does it? */
  1204. #endif
  1205.     if (PrintTestPage) EMIT(outfp, "\033z");
  1206. #ifdef vms
  1207.     /* last record is not flushed to file, unless it is completely filled */
  1208.     for (kk = (int)((*outfp)->_cnt); kk > 0; --kk) putc('\0',outfp);
  1209.     fflush(outfp);
  1210. #endif
  1211. #endif
  1212.  
  1213.     if (!G_quiet) {
  1214.         fprintf(stderr,"\nDynamically allocated storage: %ld Bytes \n",
  1215.                     (long)allocated_storage);
  1216.         fprintf(stderr,"%d characters downloaded as soft fonts\n", G_ncdl);
  1217.  
  1218. #ifdef TIMING
  1219. #ifdef BSD_TIME_CALLS
  1220.         ftime(&timebuffer);
  1221.         time = (timebuffer.time + (float)(timebuffer.millitm)/1000.0) 
  1222.            - start_time;
  1223. #else
  1224.     gettimeofday(&Tp, NULL);
  1225.     time = (Tp.tv_sec + (float)(Tp.tv_usec)/1000000.0) - start_time;
  1226. #endif
  1227.  
  1228.         if (ndone > 0) {
  1229.             fprintf(stderr,
  1230.            "Time of complete run: %.2f seconds, %d page(s), %.2f seconds/page",
  1231.                       time, ndone, time / ndone);
  1232.             fprintf(stderr," (%.2f ppm)\n",(ndone * 60) / time);
  1233.         }
  1234.         fprintf(stderr,"\n");
  1235. #endif
  1236.     }
  1237.  
  1238.     exit(G_errenc);
  1239. }
  1240.  
  1241.  
  1242. /*-->CopyFile*/   /* copy a file straight through to output */
  1243. /*********************************************************************/
  1244. /***************************** CopyFile ******************************/
  1245. /*********************************************************************/
  1246. void
  1247. CopyFile( str )
  1248. char    *str;
  1249. {
  1250.     FILE    * spfp;
  1251.     char    t;
  1252.     if ( (spfp = BINOPEN(str)) == NULL ) {
  1253.         Warning("Unable to open file %s", str );
  1254.         return;
  1255.     }
  1256.     qfprintf(stderr," [%s", str);
  1257.     for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
  1258.         putc(t, outfp);
  1259.     fclose(spfp);
  1260.     qfprintf(stderr,"]");
  1261. }
  1262.  
  1263.  
  1264. /*-->CopyHPFile*/  /* copy a HP file to output removing unwanted control codes*/
  1265. /*********************************************************************/
  1266. /***************************** CopyHPFile ******************************/
  1267. /*********************************************************************/
  1268. void
  1269. CopyHPFile( str )
  1270. char    *str;
  1271. {
  1272.     FILE    * spfp;
  1273.     char    t,numstr[20];
  1274.     int        count,rx,ry,miny,minx,num;
  1275.     
  1276.     if ( (spfp = BINOPEN(str)) == NULL ) {
  1277.         Warning("Unable to open file %s", str );
  1278.         return;
  1279.     }    
  1280.     minx=32767;            /* Set to a high value initially */
  1281.     miny=32767;
  1282.     
  1283. /* Pass through the input PCL file twice.  The first time find the smallest  */
  1284. /* x- and y-offsets so that they can be subtracted out when sending          */
  1285. /* positioning commands later.   The second pass strips the unwanted commands */
  1286. /* from the input file and outputs the rest */
  1287.     
  1288.     qfprintf(stderr," [%s", str);
  1289.     for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
  1290.     {
  1291.       if (t==0x1B)    /* Find the escape character */
  1292.         {
  1293.       t=(char) getc(spfp);
  1294.       if (t==0x2A)     /* This indiactes the start of a graphics command */
  1295.         {                                    
  1296.  
  1297.           t=(char) getc(spfp);
  1298.           switch(t)
  1299.         {
  1300.         case(0x70):
  1301.           /* These are the graphics positioning commands */
  1302.           /* Find the smallest x and y offsets */ 
  1303.           num=0;
  1304.           count=0;
  1305.           for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
  1306.             numstr[count++]=t;
  1307.           numstr[count]=0;
  1308.           num= atoi (numstr);
  1309.           
  1310.           /* Take into account the possible different ordering */
  1311.           /* of the commands (x first, y first) */
  1312.                         
  1313.           if ((t==0x59)||(t==0x79))
  1314.             {
  1315.               if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
  1316.             if (num<miny) miny=num;
  1317.               if (t==0x79)
  1318.             {
  1319.               num=0;
  1320.               count=0;
  1321.               for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
  1322.                 numstr[count++]=t;
  1323.               numstr[count]=0;
  1324.               num=atoi (numstr);
  1325.               if(numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
  1326.                 if (num<minx) minx=num;
  1327.             }
  1328.             }
  1329.           if ((t==0x58)||(t==0x78))
  1330.             {
  1331.               if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
  1332.             if (num<minx) minx=num;
  1333.               if (t==0x78)
  1334.             {
  1335.               num=0;
  1336.               count=0;
  1337.               for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
  1338.                 numstr[count++]=t;
  1339.               numstr[count]=0;
  1340.               num= atoi (numstr);
  1341.               if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
  1342.                 if (num<miny) miny=num;
  1343.             }
  1344.             }
  1345.           break;
  1346.           /* Ignore all other commands for the moment - just read them */                            
  1347.         case(0x74):    
  1348.           for (t=(char) getc(spfp);t != 0x52; t=(char) getc(spfp));
  1349.           break;
  1350.           
  1351.         case(0x72):
  1352.           for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp));
  1353.           break;
  1354.  
  1355.         case(0x62):
  1356.           num=0;
  1357.           count=0;
  1358.           /* Read in the correct number of bytes of raster graphics */
  1359.           /* so that we don't get commands and raster graphics confused */
  1360.           
  1361.           for (t=(char) getc(spfp);((t<0x40)||(t>=0x60));t=(char) getc(spfp))
  1362.             numstr[count++]=t;
  1363.           numstr[count]=0;
  1364.           if (t==0x4D)
  1365.             for(t=numstr[count=0];t!=0;t=numstr[++count]);
  1366.           if (t==0x57)
  1367.             {
  1368.               for(t=numstr[count=0];t!=0;t=numstr[++count]);
  1369.               for(count= atoi(numstr);count>0;count--)
  1370.             t=(char) getc(spfp);    
  1371.             }
  1372.           break;
  1373.                                 
  1374.         case(0x63):
  1375.           for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp));
  1376.           break;                                            
  1377.           
  1378.         default:
  1379.           break;
  1380.  
  1381.                     
  1382.         }
  1383.         }
  1384.         }
  1385.     }
  1386.     fclose(spfp);
  1387.     qfprintf(stderr,"]");
  1388.        
  1389.     if ( (spfp = BINOPEN(str)) == NULL ) {
  1390.       Warning("Unable to open file %s", str );
  1391.       return;
  1392.     }
  1393.     qfprintf(stderr," [%s", str);
  1394.  
  1395. /* Pass through the input file again but this time output the */
  1396. /* retained PCL commands */
  1397.  
  1398.     for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
  1399.       {
  1400.         if (t==0x1B)
  1401.       {
  1402.         t=(char) getc(spfp);
  1403.         if (t==0x2A)
  1404.           {                                    
  1405.         t=(char) getc(spfp);
  1406.         switch(t)
  1407.           {
  1408.           case(0x70):
  1409.             num=0;
  1410.             count=0;
  1411.             for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
  1412.               numstr[count++]=t;
  1413.             numstr[count]=0;
  1414.             num= atoi (numstr);
  1415.             if ((t==0x59)||(t==0x79))
  1416.               {
  1417.             if (numstr[0]!='+'&&numstr[0]!='-')
  1418.               {
  1419.                 /* Subtract the minimum offset found in first pass */
  1420.                 /* and add in the current vertical offset */
  1421.                 ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset;    
  1422.                 /* Output the new positioning command */
  1423.                 EMIT(outfp,"\033*p%dY",ry);
  1424.               }
  1425.             
  1426.             else if (num>=0) EMIT(outfp,"\033*p%c%dY",numstr[0],num);
  1427.             else EMIT(outfp,"\033*p%dY",num);
  1428.                                 
  1429.             if (t==0x79)
  1430.               {
  1431.                 num=0;
  1432.                 count=0;
  1433.                 for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp)) 
  1434.                   numstr[count++]=t;   /* reconstructed code */
  1435.                 numstr[count]=0;
  1436.                 num=atoi (numstr);
  1437.                 if(numstr[0]!='+'&&numstr[0]!='-')
  1438.                   {    
  1439.                 /*Add in correct horizontal offset */
  1440.                 rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset;
  1441.                 EMIT(outfp,"\033*p%dX",rx);
  1442.                   }
  1443.                 else if (num>=0) EMIT(outfp,"\033*p%c%dX",numstr[0],num);
  1444.                 else EMIT(outfp,"\033*p%dX",num);
  1445.               }
  1446.               }
  1447.                         
  1448.             if ((t==0x58)||(t==0x78))
  1449.               {
  1450.             if(numstr[0]!='+'&&numstr[0]!='-')
  1451.               {
  1452.                 /*Add in the correct horizontal offset*/
  1453.                 rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset;
  1454.                 EMIT(outfp,"\033*p%dX",rx);
  1455.               }
  1456.             else if (num>=0) EMIT(outfp,"\033*p%c%dX",numstr[0],num);
  1457.             else EMIT(outfp,"\033*p%dX",num);
  1458.                                     
  1459.             if (t==0x78)
  1460.               {
  1461.                 num=0;
  1462.                 count=0;
  1463.                 for (t=(char) getc(spfp);t<0x40;t=(char) getc(spfp))
  1464.                   numstr[count++]=t;
  1465.                 numstr[count]=0;
  1466.                 num= atoi (numstr);
  1467.                 if(numstr[0]!='+'&&numstr[0]!='-')
  1468.                   {
  1469.                 /*Add in correct vertical offset*/
  1470.                 ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset;
  1471.                 EMIT(outfp,"\033*p%dY",ry);
  1472.                   }
  1473.                 else if (num >=0) EMIT(outfp,"\033*p%c%dY",numstr[0],num);
  1474.                 else EMIT(outfp,"\033*p%dY",num);
  1475.                                }
  1476.               }
  1477.             break;
  1478.                                 
  1479.           case(0x74):
  1480.             /* Set the Raster resolution */
  1481.             EMIT(outfp,"\033*t");
  1482.             for (t=(char) getc(spfp);t != 0x52; t=(char) getc(spfp))
  1483.               putc(t,outfp);
  1484.             putc(t,outfp);
  1485.             break;
  1486.                                
  1487.           case(0x72):
  1488.             /* Raster Graphics commands such as start */
  1489.             EMIT(outfp,"\033*r");
  1490.             for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp))
  1491.               putc(t,outfp);
  1492.             putc(t,outfp);
  1493.             break;
  1494.  
  1495.           case(0x62):
  1496.             /* Transfer the correct number of bytes of raster graphics */
  1497.             EMIT(outfp,"\033*b");
  1498.             num=0;
  1499.             count=0;
  1500.             for (t=(char) getc(spfp);((t<0x40)||(t>=0x60));t=(char) getc(spfp))
  1501.               numstr[count++]=t;
  1502.             numstr[count]=0;
  1503.             if (t==0x4D)
  1504.               {
  1505.             for(t=numstr[count=0];t!=0;t=numstr[++count])
  1506.               putc(t,outfp);
  1507.             EMIT(outfp,"M");
  1508.               }
  1509.             if (t==0x57)
  1510.               {
  1511.             for(t=numstr[count=0];t!=0;t=numstr[++count])
  1512.               putc(t,outfp);
  1513.             EMIT(outfp,"W");
  1514.             for(count= atoi(numstr);count>0;count--)
  1515.               {
  1516.                 t=(char) getc(spfp);
  1517.                 putc(t,outfp);
  1518.               }    
  1519.               }
  1520.             break;
  1521.                                     
  1522.           case(0x63):
  1523.             /* Rectangular draw commands */
  1524.             EMIT(outfp,"\033*c");
  1525.             for (t=(char) getc(spfp);((t< 0x40)||(t>0x60)); t=(char) getc(spfp))
  1526.               putc(t,outfp);
  1527.             putc(t,outfp);
  1528.             break;                                            
  1529.                                        
  1530.           default:
  1531.             break;
  1532.  
  1533.                     
  1534.           }
  1535.           }
  1536.       }
  1537.       }
  1538.     fclose(spfp);
  1539.     qfprintf(stderr,"]");
  1540. }
  1541.  
  1542.  
  1543.  
  1544. /*-->DecodeArgs*/
  1545. /*********************************************************************/
  1546. /***************************** DecodeArgs ****************************/
  1547. /*********************************************************************/
  1548. void
  1549. DecodeArgs( argc, argv )
  1550. int     argc;
  1551. char    *argv[];
  1552. {
  1553.     int     argind;            /* argument index for flags      */
  1554.     char    curarea[STRSIZE];  /* current file area             */
  1555.     char    curname[STRSIZE];  /* current file name             */
  1556.     char    *tcp, *tcp1;       /* temporary character pointers  */
  1557.     char    *this_arg;
  1558.     double  x_offset=0.0, y_offset=0.0;
  1559.  
  1560. #ifndef KPATHSEA
  1561.     if ((tcp = getenv("TEXPXL")) != NULL) PXLpath = tcp;
  1562. #ifdef LJ_RESIDENT_FONTS
  1563.     if ((tcp = getenv("TFMFONTS")) != NULL) 
  1564.       TFMpath = tcp;
  1565.     else if ((tcp = getenv("TEXFONTS")) != NULL) 
  1566.       TFMpath = tcp;
  1567. #endif
  1568. #endif
  1569.  
  1570.     argind = 1;
  1571.     while (argind < argc) {
  1572.         tcp = argv[argind];
  1573.         if (*tcp == '-') {
  1574.             ++tcp;
  1575.             switch (*tcp) {
  1576. #ifdef IBM3812
  1577.             case 'b':       /* first page from alternate casette */
  1578.                 FirstAlternate = _TRUE;
  1579.                 break;
  1580. #endif
  1581.             case 'c':       /* number of copies to print */
  1582.                 if ( sscanf(tcp + 1, "%hd", &ncopies) != 1 )
  1583.                    Fatal("Argument of -c is not a valid integer\n");
  1584.                 if (ncopies<1) {
  1585.                   Warning("argument of -c < 1; set to 1!");
  1586.                   ncopies=1;
  1587.                 }
  1588.                 break;
  1589. #ifdef DEBUG
  1590.             case '-':       /* - selects Debug output */
  1591.         tcp++;
  1592.         if (*tcp == 'D') {
  1593.           Debug = _TRUE;
  1594. #ifdef KPATHSEA
  1595.                   sscanf (tcp + 1, "%u", &kpathsea_debug);
  1596. #endif
  1597.                 }
  1598.                 break;
  1599. #endif
  1600. #ifdef LJ2P
  1601.             case 'd':       /* d selects DUPLEX mode  */
  1602.         tcp++;
  1603.         if (*tcp == '1' ) DuplexMode = 1;
  1604.         else if (*tcp == '2') DuplexMode = 2;
  1605.                 else {
  1606.           Warning("Invalid DUPLEX mode, assuming DUPLEX=1, Long-Edge Binding");
  1607.           DuplexMode = 1;
  1608.         }
  1609.                 break;
  1610. #endif
  1611.             case 'D':       /* D selects DoublePage  */
  1612.                 DoublePage = _TRUE;
  1613.         tcp++;
  1614.         if (*tcp == '1' || *tcp == '2') {
  1615.           if (*tcp == '2') PrintFirstPart = _FALSE;
  1616.           else             PrintSecondPart = _FALSE;
  1617.           tcp++;
  1618.         }
  1619.         if (*tcp == '-') PrintEmptyPages = _FALSE;
  1620.                 break;
  1621. #ifdef LJ4
  1622.             case 'E':       /* do not reset printer (go) */
  1623.                 econoMode = _TRUE;
  1624.                 break;
  1625. #endif
  1626.             case 'e':       /* emit file is specified */
  1627.                 EmitFileName = ++tcp;
  1628. #ifdef MSDOS
  1629.                 /* delete trailing ':' (causing hangup) */
  1630.                 if (EmitFileName[strlen(EmitFileName)-1] == ':')
  1631.                     EmitFileName[strlen(EmitFileName)-1] = '\0';
  1632. #endif
  1633. #ifdef OS2  /* repeated to avoid problems with stupid c preprocessors  */
  1634.                 /* delete trailing ':' (causing hangup) */
  1635.                 if (EmitFileName[strlen(EmitFileName)-1] == ':')
  1636.                     EmitFileName[strlen(EmitFileName)-1] = '\0';
  1637. #endif
  1638.                 break;
  1639.             case 'f':       /* next arg is starting pagenumber */
  1640.                 if ( sscanf(tcp + 1, "%ld", &FirstPage) != 1 )
  1641.                     Fatal("Argument is not a valid integer\n");
  1642.                 FirstPageSpecified = _TRUE;
  1643.                 break;
  1644. #ifdef LJ
  1645.             case 'g':       /* do not reset printer (go) */
  1646.                 ResetPrinter = _FALSE;
  1647.                 break;
  1648. #endif
  1649.             case 'h':     /* copy header file through to output  */
  1650.                 HeaderFileName = ++tcp;
  1651.                 G_header = _TRUE;
  1652.                 break;
  1653. #if defined(LJ2P) || defined(IBM3812)
  1654.             case 'l':       /* landscape  */
  1655.                 Landscape = _TRUE;
  1656.                 break;
  1657. #endif
  1658. #ifdef MAKETEXPK
  1659.         case 'M':
  1660.         /* -M, -M1 => don't make font; -M0 => do.  */
  1661.             makeTexPK = *(tcp + 1) == '0';
  1662.             break;
  1663. #endif
  1664.             case 'x':       /* specify x-offset */
  1665.                 this_arg = 0;
  1666.                 if (!(*++tcp)) {
  1667.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1668.                 } else {
  1669.                     this_arg = tcp;
  1670.                 }
  1671.                 if (!this_arg
  1672.                      || sscanf(this_arg,"%lf", &x_offset) != 1)
  1673.          Fatal("Argument of -x is not a valid floating point number\n");
  1674.                 break;
  1675.             case 'y':       /* specify y-offset */
  1676.                 this_arg = 0;
  1677.                 if (!(*++tcp)) {
  1678.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1679.                 } else {
  1680.                     this_arg = tcp;
  1681.                 }
  1682.                 if (!this_arg || sscanf(this_arg, "%lf", &y_offset) != 1)
  1683.                 Fatal("Argument of -y is not a valid floating point number\n");
  1684.                 break;
  1685.             case 'X':       /* specify X-origin in dots */
  1686.                 this_arg = 0;
  1687.                 if (!(*++tcp)) {
  1688.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1689.                 } else {
  1690.                     this_arg = tcp;
  1691.                 }
  1692.                 if (!this_arg || sscanf(this_arg,"%hd", &x_origin) != 1)
  1693.                    Fatal("Argument of -X is not a valid integer\n");
  1694.                 break;
  1695.             case 'Y':       /* specify Y-origin in dots */
  1696.                 this_arg = 0;
  1697.                 if (!(*++tcp)) {
  1698.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1699.                 } else {
  1700.                     this_arg = tcp;
  1701.                 }
  1702.                 if (!this_arg ||
  1703.                      sscanf(this_arg, "%hd", &y_origin) != 1)
  1704.                         Fatal("Argument of -Y is not a valid integer\n");
  1705.                 break;
  1706.             case 'm':       /* specify magnification to use */
  1707.                 switch ( (*++tcp) ) {
  1708.                 case '#':
  1709.                      /* next arg is a magnification to use */
  1710.                     if ( sscanf(tcp + 1, "%ld", &usermag) != 1 )
  1711.                        Fatal("Argument of mag is not a valid integer\n");
  1712.                     break;
  1713.                 case '0':
  1714.                     usermag = 1000;
  1715.                     break;
  1716.                 case 'h':
  1717.                 case 'H':
  1718.                     usermag = 1095;
  1719.                     break;
  1720.                 case '1':
  1721.                     usermag = 1200;
  1722.                     break;
  1723.                 case 'q':
  1724.                     usermag = 1250;
  1725.                     break;
  1726.                 case '2':
  1727.                     usermag = 1440;
  1728.                     break;
  1729.                 case '3':
  1730.                     usermag = 1728;
  1731.                     break;
  1732.                 case '4':
  1733.                     usermag = 2074;
  1734.                     break;
  1735.                 case '5':
  1736.                     usermag = 2488;
  1737.                     break;
  1738.                 default:
  1739.                     Fatal("%c is a bad mag step\n", *tcp);
  1740.                 }
  1741.                 break;
  1742. #ifdef SUPERCOMMENT
  1743.             case 'o':     /* PostScript command to send */
  1744.                 if ( ++argind >= argc )
  1745.                     Fatal("No argument following -o\n", 0);
  1746.                 PScmd[nps++] = argv[argind];
  1747.                 break;
  1748. #endif
  1749.             case 'p':       /* print n pages  */
  1750.                 if ( sscanf(tcp + 1, "%ld", &PrintPages) != 1 )
  1751.                     Fatal("Argument is not a valid integer\n");
  1752.                 if (PrintPages < 1)
  1753.                   Fatal("Argument of -p must be greater than 0\n");
  1754.                 break;
  1755.             case 'q':       /* quiet operation */
  1756.                 G_quiet = _TRUE;
  1757.                 break;
  1758.             case 'r':       /* switch order to process pages */
  1759.                 Reverse = (bool)(!Reverse);
  1760.                 break;
  1761. #ifdef LJ
  1762.             case 's':       /* specify X-origin in dots */
  1763.                 this_arg = 0;
  1764.                 if (!(*++tcp)) this_arg = (++argind >= argc ? 0 : argv[argind]);
  1765.                 else           this_arg = tcp;
  1766.                 if (!this_arg || sscanf(this_arg,"%hd", &pagesize) != 1)
  1767.                    Fatal("Argument of -s is not a valid integer\n");
  1768. /*
  1769.  * The original pgsiz_dots assumed  a resolution of 300dpi. This loses
  1770.  * at 600dpi so we must scale all.
  1771.  */
  1772.                 switch (pagesize) {
  1773. /* 
  1774.  * The original pgsiz_dots assumed  a resolution of 300dpi. This loses
  1775.  * at 600dpi so we must scale all. 
  1776.  */
  1777.                 case 1: pgsiz_dots = 3150; break;         /* executive */
  1778.                 case 2: pgsiz_dots = 3300; break;         /* letter */
  1779.                 case 3: pgsiz_dots = 4200; break;         /* legal */
  1780.                 case 26: pgsiz_dots = 3507; break;        /* a4 */
  1781.                 case 80: pgsiz_dots = 2250; break;        /* monarc */
  1782.                 case 81: pgsiz_dots = 2850; break;        /* com10 */
  1783.                 case 90: pgsiz_dots = 2598; break;        /* int dl */
  1784.                 case 91: pgsiz_dots = 2704; break;        /* int c5 */
  1785.                 default: Fatal(
  1786. #ifndef vms
  1787.                    "%hd is a bad value for pagesize (1,2,3,26,80,81,90,91)",
  1788. #else
  1789.                    "%d is a bad value for pagesize (1,2,3,26,80,81,90,91)",
  1790. #endif
  1791.                    pagesize);
  1792.                 }
  1793.                 break;
  1794. #endif
  1795.             case 't':       /* ending pagenumber */
  1796.                 if ( sscanf(tcp + 1, "%ld", &LastPage) != 1 )
  1797.                     Fatal("Argument is not a valid integer\n");
  1798.                 LastPageSpecified = _TRUE;
  1799.                 break;
  1800.             case 'v':    /* verbatim mode (print pxl-file names) */
  1801.                 G_noverbatim = _FALSE;
  1802.                 break;
  1803.             case 'w':       /* don't print out warnings */
  1804.                 G_nowarn = _TRUE;
  1805.                 break;
  1806. #ifdef LJ
  1807.             case 'z':
  1808.                 PrintTestPage = (bool)(!PrintTestPage);
  1809.                 break;
  1810. #endif
  1811. #ifdef LJ4
  1812.             case 'R':       /* number of copies to print */
  1813.                 if ( sscanf(tcp + 1, "%d", &RESOLUTION) != 1 )
  1814.                    Fatal("Argument of -R is not a valid integer\n");
  1815.                 if (RESOLUTION != 300 && RESOLUTION != 600 ) {
  1816.                   Warning("Resolution must be 300 or 600! Assuming 300.dpi.");
  1817.                   RESOLUTION=300;
  1818.                 } else {
  1819.           if (RESOLUTION == 600) {
  1820.             MFMODE = MFMODE600;
  1821.             x_origin = 600;
  1822.             y_origin = 600;
  1823.           }
  1824.         }
  1825.                 break;
  1826. #endif
  1827.             default:
  1828.                 fprintf(stderr, "%c is not a legal flag\n", *tcp);
  1829.             }
  1830.         } else {
  1831.  
  1832.             (void) strcpy(filename, tcp);
  1833.         if(!strcmp(filename, "-")) {
  1834.            EmitFileName="-";
  1835.           dvifp=stdin;
  1836.         } else {
  1837.           tcp = strrchr(argv[argind], '/');
  1838.           /* split into directory + file name */
  1839.           if (tcp == NULL)  {
  1840.                 curarea[0] = '\0';
  1841.                 tcp = argv[argind];
  1842.           } else {
  1843.                 (void) strcpy(curarea, argv[argind]);
  1844.                 curarea[tcp-argv[argind]+1] = '\0';
  1845.                 tcp += 1;
  1846.           }
  1847.  
  1848.           (void) strcpy(curname, tcp);
  1849.           /* split into file name + extension */
  1850.           tcp1 = strrchr(tcp, '.');
  1851.           if (tcp1 == NULL) {
  1852.                 (void) strcpy(rootname, curname);
  1853.                 strcat(curname, ".dvi");
  1854.           } else {
  1855.                 *tcp1 = '\0';
  1856.                 (void) strcpy(rootname, curname);
  1857.                 *tcp1 = '.';
  1858.           }
  1859.  
  1860.           (void) strcpy(filename, curarea);
  1861.           (void) strcat(filename, curname);
  1862.  
  1863.           if ((dvifp = BINOPEN(filename)) == NULL)  {
  1864.         /* do not insist on .dvi */
  1865.         if (tcp1 == NULL)  {
  1866.           curname[strlen (curname) - 4] = '\0';
  1867.           filename[strlen (filename) - 4] = '\0';
  1868.         }
  1869.         if (tcp1 != NULL || (dvifp = BINOPEN(filename)) == NULL)  {
  1870.           perror (filename);
  1871.           exit (EXIT_FAILURE);
  1872.         }
  1873.           }
  1874.         } /* dvi filename != '-" */
  1875.         }
  1876.         argind++;
  1877.     }
  1878.  
  1879. #ifdef LJ4
  1880.     pgsiz_dots *= (int)(RESOLUTION/300); /* rescale dots to page */
  1881. #endif    
  1882.     x_goffset = (short) MM_TO_PXL(x_offset) + x_origin;
  1883.     y_goffset = (short) MM_TO_PXL(y_offset) + y_origin;
  1884.  
  1885.     if (dvifp == NULL)  {
  1886.       fprintf(stderr,"\nThis is the DVI to %s converter version %s",
  1887.           PRINTER, VERSION);
  1888. #ifdef SEVENBIT
  1889.       fprintf(stderr,", 7bit");
  1890. #endif
  1891.       fprintf(stderr," (%s)\n", OS);
  1892.       fprintf(stderr,"usage: %s [OPTIONS] dvifile\n", G_progname);
  1893.  
  1894.       fprintf(stderr,"OPTIONS are:\n");
  1895. #ifdef DEBUG
  1896.       fprintf(stderr,"\t--D ..... turns debug output on\n");
  1897. #endif
  1898.       fprintf(stderr,
  1899.         "\t-aX ..... X= searchpath leading to pixel-files (.pk or .pxl)\n");
  1900. #ifdef IBM3812
  1901.       fprintf(stderr,
  1902.         "\t-b  ..... take paper for first page from alternate casette\n");
  1903. #endif
  1904.       fprintf(stderr,"\t-cX ..... X= number of copies\n");
  1905. #ifdef LJ2P
  1906.       fprintf(stderr,"\t-dX ..... duplex, X=1: long-edge, 2: short-edge binding\n");
  1907. #endif
  1908.       fprintf(stderr,"\t-D  ..... turns doublepage output on; ");
  1909.       fprintf(stderr,"-D1 odd pages only, -D2 even\n");
  1910. #ifdef LJ4
  1911.       fprintf(stderr,"\t-E  ..... print in econo-mode\n");
  1912. #endif
  1913.       fprintf(stderr,"\t-eX ..... X= output file\n");
  1914.       fprintf(stderr,"\t-fX ..... print from begin of page number X\n");
  1915. #ifdef LJ
  1916.       fprintf(stderr,
  1917.           "\t-g  ..... do not reset printer at begin of job (go)\n");
  1918. #endif
  1919.       fprintf(stderr,"\t-hX ..... X= name of headerfile\n");
  1920. #ifdef LJ2P
  1921.       fprintf(stderr,"\t-l  ..... landscape mode\n");
  1922. #endif
  1923. #ifdef MAKETEXPK
  1924.       fprintf(stderr,"\t-MX ..... Don't generate missing PK files\n");
  1925. #endif
  1926.       fprintf(stderr,"\t-mX ..... magnification X=0;h;1;2;3;4;5;#xxxx\n");
  1927.       fprintf(stderr,"\t-pX ..... print X pages\n");
  1928.       fprintf(stderr,"\t-q  ..... quiet operation\n");
  1929.       fprintf(stderr,"\t-r  ..... process pages in reverse order\n");
  1930. #ifdef LJ4
  1931.       fprintf(stderr,"\t-RX ..... set resolution to 300 or 600 dpi\n");
  1932. #endif
  1933. #ifdef LJ
  1934.       fprintf(stderr,"\t-sX ..... set paper size to X (see documentation)\n");
  1935. #endif
  1936.       fprintf(stderr,"\t-tX ..... print to end of page number X\n");
  1937.       fprintf(stderr,"\t-w  ..... don't print out warnings\n");
  1938.       fprintf(stderr,"\t-v  ..... tell user which pixel-files are used\n");
  1939.       fprintf(stderr,"\t-xX ..... X= x-offset on printout in mm\n");
  1940.       fprintf(stderr,"\t-yX ..... X= y-offset on printout in mm\n");
  1941.       fprintf(stderr,"\t-XO ..... O= x page origin in dots (default=%d)\n",
  1942.             XDEFAULTOFF );
  1943.       fprintf(stderr,"\t-YO ..... O= y page origin in dots (default=%d)\n",
  1944.             YDEFAULTOFF );
  1945. #ifdef LJ
  1946.       fprintf(stderr,
  1947.           "\t-z  ..... print test page with pagecounter after job\n");
  1948. #endif
  1949.       fprintf(stderr,
  1950.       "\t-   ..... dvifile is stdin (must be seekable); implies -e-\n");
  1951.       exit(1);
  1952.     }
  1953.     if (EQ(EmitFileName, "")) {
  1954.         if ((EmitFileName = (char *)malloc( STRSIZE )) != NULL)
  1955.             allocated_storage += STRSIZE;
  1956.         else
  1957.             Fatal("Can't allocate storage of %d bytes\n",STRSIZE);
  1958.         (void) strcpy(EmitFileName, curname);
  1959.         if ((tcp1 = strrchr(EmitFileName, '.'))) 
  1960.       *tcp1 = '\0';
  1961.     strcat(EmitFileName, EMITFILE_EXTENSION);
  1962.     }
  1963. }
  1964.  
  1965.  
  1966. /*-->DoConv*/
  1967. /*********************************************************************/
  1968. /********************************  DoConv  ***************************/
  1969. /*********************************************************************/
  1970. long4
  1971. DoConv(num, den, convResolution)
  1972. long4    num, den;
  1973. int     convResolution;
  1974. {
  1975.     /*register*/ double conv;
  1976.     conv = ((double)num / (double)den) *
  1977.             ((double)mag / 1000.0) *
  1978.           ((double)convResolution/254000.0);
  1979.  
  1980.     return((long4) ((1.0/conv)+0.5));
  1981. }
  1982.  
  1983.  
  1984. /*-->DoSpecial*/
  1985. /*********************************************************************/
  1986. /*****************************  DoSpecial  ***************************/
  1987. /*********************************************************************/
  1988. typedef enum  { None, String, Integer /*, Number, Dimension*/ }
  1989.  
  1990.  
  1991. ValTyp;
  1992. typedef struct {
  1993.     char    *Key;       /* the keyword string */
  1994.     char    *Val;       /* the value string */
  1995.     ValTyp  vt;         /* the value type */
  1996.     union {         /* the decoded value */
  1997.         int     i;
  1998.         float   n;
  1999.     } v;
  2000. } KeyWord;
  2001. typedef struct {
  2002.     char    *Entry;
  2003.     ValTyp  Typ;
  2004. } KeyDesc;
  2005. #define PSFILE 0
  2006. #define ORIENTATION 1
  2007. #define RESETPOINTS 2
  2008. #define DEFPOINT 3
  2009. #define FILL 4
  2010. #define GRAY 5
  2011. #define PATTERN 6
  2012. #define HPFILE 7
  2013. KeyDesc KeyTab[] = {
  2014.     { "file", String },
  2015.     { "orientation", Integer},
  2016.     { "resetpoints", String},
  2017.     { "defpoint", String},
  2018.     { "fill", String},
  2019.     { "gray", Integer},
  2020.     { "pattern", Integer},
  2021.     { "hpfile", String}
  2022.    /*,
  2023.              {"hsize", Dimension},
  2024.              {"vsize", Dimension},
  2025.              {"hoffset", Dimension},
  2026.              {"voffset", Dimension},
  2027.              {"hscale", Number},
  2028.              {"vscale", Number}*/
  2029.  
  2030.  
  2031. };
  2032.  
  2033.  
  2034. #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
  2035. void
  2036. DoSpecial( str, n )
  2037. /* interpret a \special command, made up of keyword=value pairs */
  2038. char    *str;
  2039. int     n;
  2040. {
  2041.   char    spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE];
  2042.   char    *sf = NULL;
  2043.   float   x,y;
  2044.   long4     x_pos, y_pos;
  2045.   KeyWord k;
  2046.   int     i, j, j1;
  2047.   static int   GrayScale=10, Pattern=1;
  2048.   static bool  GrayFill=_TRUE;
  2049.   static long4  p_x[80], p_y[80];
  2050.   str[n] = '\0';
  2051.   spbuf[0] = '\0';
  2052.  
  2053.   SetPosn(h, v);
  2054.   while ( (str = GetKeyStr(str, &k)) != NULL ) {
  2055.     /* get all keyword-value pairs */
  2056.     /* for compatibility, single words are taken as file names */
  2057.     if ( k.vt == None && access(k.Key, 0) == 0) {
  2058.         if ( sf )
  2059.             Warning("More than one \\special file name given. %s ignored", sf);
  2060.         (void) strcpy(spbuf, k.Key);
  2061.         sf = spbuf;
  2062. /*
  2063.         for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
  2064. */
  2065.     } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 )
  2066.         switch (i) {
  2067.         case PSFILE:
  2068.         case HPFILE:
  2069.             if ( sf )
  2070.                 Warning("More than one \\special file name given. %s ignored",
  2071.                             sf);
  2072.             (void) strcpy(spbuf, k.Val);
  2073.             sf = spbuf;
  2074. /*
  2075.             for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++) ;
  2076. */
  2077.             break;
  2078.         case ORIENTATION:
  2079. #ifdef IBM3812
  2080.             if ((k.v.i >= 0) && (k.v.i < 4)) {
  2081.                 last_ry = UNKNOWN;
  2082.                 sprintf(PMPformat, "\322%c", (unsigned char)k.v.i);
  2083.                 PMPout(2, PMPformat);
  2084.         if (k.v.i == 1) Landscape = _TRUE;
  2085.         else if (k.v.i == 0) Landscape = _FALSE;
  2086. #endif
  2087. #ifdef LJ
  2088.             if ((k.v.i >= 0) && (k.v.i < 2)) {
  2089.                 last_ry = UNKNOWN;
  2090.                 EMIT(outfp, "\033&l%dO\033*rF", (unsigned char)k.v.i);
  2091. #endif
  2092.             } else
  2093.                 Warning( "Invalid orientation (%d)given; ignored.", k.v.i);
  2094.             break;
  2095.         case RESETPOINTS:
  2096.             (void) strcpy(spbuf, k.Val);
  2097.  
  2098.             sf = NULL;
  2099.             break;
  2100.  
  2101.         case DEFPOINT:
  2102.           (void) strcpy(spbuf, k.Val);
  2103.            i=sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys);
  2104.            if (i>0) {
  2105.               x_pos=h; y_pos=v;
  2106.               if (i>1) {
  2107.                   if (sscanf(xs,"%fpt",&x)>0) {
  2108.                      fprintf(stderr,"x = %f\n",x);
  2109.                      x_pos = PT_TO_DVI(x);
  2110.              }
  2111.               }
  2112.               if (i>2) {
  2113.                   if (sscanf(ys,"%fpt",&y)>0) {
  2114.                      fprintf(stderr,"y = %f\n",y);
  2115.                      y_pos = PT_TO_DVI(y);
  2116.                 }
  2117.               }
  2118.               p_x[j]=x_pos;
  2119.               p_y[j]=y_pos;
  2120.            } else
  2121.              Warning("invalid point definition\n");
  2122.  
  2123.            sf = NULL;
  2124.            break;
  2125.  
  2126.         case FILL:
  2127.           (void) strcpy(spbuf, k.Val);
  2128.            i=sscanf(spbuf,"%d/%d %s",&j,&j1,xs);
  2129.            if (i>1) {
  2130. #ifdef LJ
  2131.               SetPosn(p_x[j], p_y[j]);
  2132.               x_pos = (long4)PIXROUND(p_x[j1]-p_x[j], hconv);
  2133.               y_pos = (long4)PIXROUND(p_y[j1]-p_y[j], vconv);
  2134.               if (labs(x_pos)<labs(y_pos)) x_pos=x_pos+3;
  2135.               else                         y_pos=y_pos+3;
  2136.               if (GrayFill) {
  2137.         EMIT(outfp, "\033*c%lda%ldb%dg2P", (long)x_pos, (long)y_pos, GrayScale);
  2138.               } else {
  2139.         EMIT(outfp, "\033*c%lda%ldb%dg3P", (long)x_pos, (long)y_pos, Pattern);
  2140.               }
  2141.               last_ry = UNKNOWN;
  2142. #endif
  2143.            }
  2144.            break;
  2145.         case GRAY:
  2146.             if ((k.v.i >= 0) && (k.v.i < 101)) {
  2147.                 GrayScale = k.v.i;
  2148.                 GrayFill = _TRUE;
  2149.             } else
  2150.                 Warning( "Invalid gray scale (%d) given; ignored.", k.v.i);
  2151.             break;
  2152.         case PATTERN:
  2153.             if ((k.v.i >= 0) && (k.v.i < 7)) {
  2154.                 Pattern = k.v.i;
  2155.                 GrayFill = _FALSE;
  2156.             } else
  2157.                 Warning( "Invalid pattern (%d) given; ignored.", k.v.i);
  2158.             break;
  2159.  
  2160.         default:
  2161.             Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val);
  2162.             break;
  2163.         }
  2164.     else
  2165.         Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key);
  2166.   }
  2167.   if ( sf ) {
  2168.     last_ry = UNKNOWN;
  2169. #ifdef IBM3812
  2170.     PMPflush;
  2171. #endif
  2172.     if (i==HPFILE)
  2173.       CopyHPFile( sf );
  2174.     else
  2175.       CopyFile( sf );
  2176.   }
  2177. }
  2178.  
  2179.  
  2180. /*-->EmitChar*/
  2181. /**********************************************************************/
  2182. /****************************  EmitChar  ******************************/
  2183. /**********************************************************************/
  2184. void                     /* output a character bitmap */
  2185. EmitChar(c, ce)
  2186. long4    c;
  2187. struct char_entry *ce;
  2188. {
  2189.     register int    i;
  2190.     register unsigned char  *sl;
  2191.     unsigned short  nbpl, nwpl;
  2192.     long4    total;
  2193. #ifdef LJ
  2194.     unsigned char cnv_buffer[10];
  2195. #endif
  2196.  
  2197.   
  2198. #ifdef LJ
  2199. /*
  2200. printf("Emit character %c(%d) id=%d, yoff=%d[%d], w=%d[%d], h=%d[%d]\n",
  2201.         (char)c,(int)c,
  2202.     fontptr->plusid,
  2203.     ce->yOffset, fontptr->max_yoff,
  2204.     ce->width,   fontptr->max_width,
  2205.     ce->height,  fontptr->max_height
  2206. );
  2207. */
  2208. #endif
  2209.  
  2210.  
  2211.  
  2212.     if ( fontptr->ncdl == 0 ) {
  2213. #ifdef IBM3812
  2214.         used_fontstorage += 1028;
  2215. #endif
  2216. #ifdef LJ
  2217.         if (fontptr->max_width == 0) { /* we have no realistic values */
  2218.                 fontptr->max_yoff = CHAR_HEIGTH_LARGE;
  2219.                 fontptr->max_width = CHAR_WIDTH_LARGE;
  2220.                 fontptr->max_height = CHAR_HEIGTH_LARGE*2;
  2221.         }
  2222.  
  2223.         /* open font dict before first char, set active font */
  2224.         INT_ASCII(cnv_buffer,fontptr->plusid);
  2225. #ifdef LJ4
  2226.         EMIT(outfp, "\033*c%sD\033)s68W", cnv_buffer);
  2227.         EMITB(6, "\0\104\024\2\0\0");   
  2228. #else
  2229.         EMIT(outfp, "\033*c%sD\033)s26W", cnv_buffer);
  2230. #ifdef SEVENBIT
  2231.         EMITB(6, "\0\032\0\1\0\0");   
  2232. #else
  2233.         EMITB(6, "\0\032\0\2\0\0");   
  2234. #endif
  2235. #endif /* LJ 4 */
  2236.         EMITWORD( fontptr->max_yoff);
  2237.         EMITWORD( fontptr->max_width);
  2238.         EMITWORD( fontptr->max_height);
  2239.         EMITB(8, "\0\1\1\25\0\4\0\4");
  2240.         EMITB(6, "\0\0\0\0\0\0");
  2241. #ifdef LJ4
  2242.     EMITB(22,"\0\0\0\0\0\0\0\0\0\0\0\0\0\377\0\0\0\0\0\0\0\0");
  2243.     EMITB(16,"                ");
  2244.     EMITB(4 ,"\2\130\2\130"); 
  2245. #endif
  2246.         EMIT(outfp, "\033*c4F");
  2247. #endif
  2248.     }
  2249.     if ( fontptr != prevfont ) {   /* because this isn't done on pass 0 */
  2250. #ifdef LJ
  2251.         INT_ASCII(cnv_buffer,fontptr->plusid);
  2252.         EMIT(outfp, "\033(%sX", cnv_buffer);
  2253. #endif
  2254.         prevfont = fontptr;
  2255.     }
  2256.  
  2257. #ifdef USEPXL
  2258.     if (fontptr->id == pk89)   {
  2259.         nwpl = 0; /* initialize variable */
  2260.         nbpl = ((int)(ce->width) +  7) >> 3;
  2261.         total = (long4)ce->height * nbpl;
  2262.     } else if (fontptr->id == id1002)   {
  2263.         nwpl = 0; /* initialize variable */
  2264.         nbpl = ((int)(ce->width) +  7) >> 3;
  2265.         total = (long4)ce->height * nbpl;
  2266.     } else if (fontptr->id == id1001) {
  2267.         nwpl = ((int)(ce->width) + 31) >> 5;
  2268.         nbpl = ((int)(ce->width) + 7) >> 3;
  2269.         total = (long4)ce->height * nbpl;
  2270.     } else {
  2271.       /* should never be necessary */
  2272.       nwpl = 0;
  2273.       nbpl = 0;
  2274.       total = 0;
  2275.     }
  2276. #else
  2277.     nbpl = (num_cols + 7) >> 3;
  2278.     total = num_rows * nbpl;
  2279. #endif
  2280. /***************************************************************
  2281.     if ( ((char) c == 'i') && (fontptr->plusid == 0)) {
  2282.         long4 j;
  2283.         fprintf(stderr, "cols=%ld, ncols=%ld\n",(long)nwpl,(long)nbpl);
  2284.  
  2285.         fprintf(stderr, "%ld Bytes:->",(long)total);
  2286.         for (j=0; j<total;j++) {
  2287.             char *ch; char ic;
  2288.             ch = (char *)(ce->where.address.pixptr);
  2289.             ic = *(ch+j);
  2290.             fprintf(stderr,"%X.",ic);
  2291.                 }
  2292.         fprintf(stderr,"<- Now Emitting\n");
  2293.         }
  2294. ***************************************************************/
  2295. #ifdef USEPXL
  2296. #ifdef IBM3812
  2297.     if ((short)(ce->height) - ce->yOffset > 55) {
  2298.         ce->yyOffset = (short) ce->height - ce->yOffset;
  2299.         ce->yOffset  = (short) ce->height;
  2300.     } else {
  2301.         ce->yyOffset = (short) 0;
  2302.     }
  2303. #endif
  2304. #ifdef LJ
  2305.         ce->yyOffset = (short) 0;
  2306. #endif
  2307. #endif
  2308.  
  2309.     /* ce->cw = (long4)(((double)ce->tfmw / (double)hconv) +0.5); */
  2310.     /* set active font to nn, load font pattern  xx ... */
  2311. #ifdef IBM3812
  2312.     PMPcont(total + 9);
  2313. #ifdef USEPXL
  2314.     sprintf(PMPformat, "\323%c\360%c%c%c",
  2315.         (unsigned char)fontptr->plusid,
  2316.         (unsigned char)VisChar((char)c),
  2317.         (unsigned char)ce->height,
  2318.         (unsigned char)ce->width);
  2319.     PMPout(6, PMPformat);
  2320.     PMPoutC((char)(-(ce->xOffset)));
  2321.     PMPoutC((char)(ce->cw - (-ce->xOffset + ce->width)));
  2322.     PMPoutC((char)(ce->yOffset));
  2323. #else
  2324.     sprintf(PMPformat, "\323%c\360%c%c%c",
  2325.         (unsigned char)fontptr->plusid,
  2326.         (unsigned char)VisChar((char)c),
  2327.         (unsigned char)num_rows,
  2328.         (unsigned char)num_cols);
  2329.     PMPout(6, PMPformat);
  2330.     PMPoutC((char)(-x_offset));
  2331.     PMPoutC((char)(ce->cw - (-x_offset + num_cols)));
  2332.     PMPoutC((char)num_rows-y_offset);
  2333. #endif
  2334. #endif
  2335. #ifdef LJ
  2336.     INT_ASCII(cnv_buffer,fontptr->plusid);
  2337.     EMIT(outfp, "\033*c%sd%dE\033(s%ldW", cnv_buffer,
  2338.         (unsigned int)VisChar((char)c), (long)(total + 16));
  2339.     EMITB(4, "\4\0\016\1");
  2340. /*    EMITC((char)(Landscape==_TRUE)); */
  2341.     EMITC((char)0);
  2342.     EMITC((char)0);
  2343. #ifdef USEPXL
  2344.     EMITWORD(-ce->xOffset);
  2345.     EMITWORD(ce->yOffset);
  2346.     EMITWORD(ce->width);
  2347.     EMITWORD(ce->height);
  2348. #else
  2349.     EMITWORD(-x_offset);
  2350.     EMITWORD(num_rows-y_offset);
  2351.     EMITWORD(num_cols);
  2352.     EMITWORD(num_rows);
  2353. #endif
  2354.     EMITWORD((int)ce->cw * 4);
  2355. #endif
  2356. #ifdef USEPXL
  2357.  
  2358.     if (fontptr->id == pk89)
  2359.         PkRaster(ce, _FALSE);
  2360.     else if (fontptr->id == id1002)
  2361.         for (i = 0; i < (int) ce->height; i++) {
  2362.             sl = ((unsigned char *)(ce->where.address.pixptr) + i * nbpl);
  2363.             EMITL(nbpl, sl);
  2364.         }
  2365.     else if (fontptr->id == id1001)
  2366.         for (i = 0; i < (int) ce->height; i++) {
  2367.             sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
  2368.             EMITL(nbpl, sl);
  2369.         }
  2370. #else
  2371.     for (i = num_rows; i > 0; i--)
  2372.       {
  2373.         EMITL (nbpl, bits + (i-1) * nbpl);
  2374.       }
  2375. #endif
  2376. #ifdef IBM3812
  2377. #ifdef USEPXL
  2378.     used_fontstorage += (long4)ce->height * ((ce->width + 15) >> 4)
  2379.         *2 + 14;
  2380. #else
  2381.     used_fontstorage += (long4)num_rows * ((num_cols + 15) >> 4)
  2382.         *2 + 14;
  2383. #endif
  2384. #endif
  2385. #ifdef LJ
  2386. #ifdef USEPXL
  2387.     used_fontstorage += 64 * (((int)((ce->height * ce->width) - 1) / 64) + 1);
  2388. #else
  2389.     used_fontstorage += 64 * ((((num_rows * num_cols) - 1) / 64) + 1);
  2390. #endif
  2391. #endif
  2392.     fontptr->ncdl += 1;
  2393.     G_ncdl += 1;
  2394. }
  2395.  
  2396.  
  2397. /*-->RasterLine*/
  2398. /**********************************************************************/
  2399. /****************************  RasterLine  ****************************/
  2400. /**********************************************************************/
  2401. void
  2402. RasterLine(ce, nbpl, current_line, buffer)
  2403. struct char_entry *ce;
  2404. unsigned short  nbpl, current_line;
  2405. char    *buffer;
  2406. {
  2407. #ifdef IBM3812
  2408.     long4    total;
  2409.     static unsigned short   maxlines;
  2410.  
  2411.     if (current_line == 0) {
  2412. #ifdef USEPXL
  2413.         maxlines = ce->height;
  2414.  
  2415.         MoveVert(-ce->yOffset);      /* move cursor up */
  2416.         MoveHor(-ce->xOffset);       /* move cursor right */
  2417. #else
  2418.         maxlines = num_rows;
  2419.  
  2420.         MoveVert(-(num_rows-y_offset));      /* move cursor up */
  2421.         MoveHor(-x_offset);       /* move cursor right */
  2422. #endif
  2423.         last_ry = UNKNOWN;       /* next time full positioning */
  2424.     }
  2425.  
  2426.     if (current_line % maxlines == 0) {
  2427.         if (current_line > 0) {    /* maxlines lines have been printed*/
  2428.             MoveVert(maxlines);   /*   move cursor down     */
  2429.             last_ry = UNKNOWN;    /* next time full positioning */
  2430.         }
  2431. #ifdef USEPXL
  2432.         total = (long4)(ce->height - current_line) * (long4)nbpl;
  2433. #else
  2434.         total = (long4)(num_rows - current_line) * (long4)nbpl;
  2435. #endif
  2436.         if ((total + 9) > 65535) {
  2437.             maxlines = (unsigned short)((65535 - 9) / nbpl);
  2438.             total = (long4)maxlines * (long4)nbpl;
  2439.         }
  2440.  
  2441.         PMPcont(total + 9);
  2442.         PMPout(2, "\365\0");
  2443.         EMITWORD(maxlines);
  2444. #ifdef USEPXL
  2445.         EMITWORD(ce->width);
  2446. #else
  2447.         EMITWORD(num_cols);
  2448. #endif
  2449.         PMPoutC((unsigned char) (total >> 16) & 0xFF);
  2450.         PMPoutC((unsigned char) (total >> 8 ) & 0xFF);
  2451.         PMPoutC((unsigned char)  total     & 0xFF);
  2452.     }
  2453.     EMITL((int)nbpl, buffer);
  2454. #endif
  2455. #ifdef LJ
  2456.     register int    emitbytes;
  2457.  
  2458.     for (emitbytes = (int)nbpl;
  2459.         (*(buffer + emitbytes - 1) == '\0') && (emitbytes > 0);
  2460.         emitbytes--) ;
  2461.     EMIT(outfp, "\033*b%dW", emitbytes);
  2462.     EMITL(emitbytes, buffer);
  2463. #endif
  2464. }
  2465.  
  2466.  
  2467. /*-->RasterChar*/
  2468. /**********************************************************************/
  2469. /****************************  RasterChar  ****************************/
  2470. /**********************************************************************/
  2471. void                     /* raster a character bitmap */
  2472. RasterChar(ce)
  2473. struct char_entry *ce;
  2474. {
  2475.     int     i;
  2476.     register unsigned char  *sl;
  2477.     unsigned short  nbpl, nwpl;
  2478.     unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
  2479.  
  2480. #ifdef DEBUG
  2481.     if (Debug)
  2482.         fprintf(stderr,"Raster character ...size=%d \n", (int)ce->charsize );
  2483. #endif
  2484.  
  2485. #ifdef USEPXL
  2486.     if (fontptr->id == pk89)   {
  2487.         nwpl = 0; /* initialize variable */
  2488.         nbpl = ((int)(ce->width) +  7) >> 3;
  2489.     } else if (fontptr->id == id1002)   {
  2490.         nwpl = 0; /* initialize variable */
  2491.         nbpl = ((int) ce->width +  7) >> 3;
  2492.     } else if (fontptr->id == id1001) {
  2493.         nwpl = ((int) ce->width + 31) >> 5;
  2494.         nbpl = ((int) ce->width + 7) >> 3;
  2495.     } else {
  2496.       /* should never be necessary */
  2497.       nwpl = 0;
  2498.       nbpl = 0;
  2499.     }
  2500. #else
  2501.     nbpl = (num_cols + 7) >> 3;
  2502. #endif
  2503.  
  2504. #ifdef LJ
  2505.     EMIT(outfp, "\033*t%dR\033*r1A",RESOLUTION);
  2506. #endif
  2507.                                             { /* read pixel from file */
  2508.     if ((ce->charsize == HUGE_SIZE) && (fontptr->id != pk89))
  2509.         OpenFontFile();
  2510. #ifdef USEPXL
  2511.         fseek(pxlfp, ce->where.address.fileOffset, 0);
  2512. #else
  2513.         fseek(gfin, ce->where.address.fileOffset, 0);
  2514.         gettochar();
  2515.         readbits();
  2516. #endif
  2517.     }
  2518.  
  2519. #ifdef USEPXL
  2520.     if (fontptr->id == pk89)
  2521.         PkRaster(ce, _TRUE);
  2522.     else if (fontptr->id == id1002) {
  2523.         for (i = 0; i < (int) ce->height; i++) {
  2524.             if (ce->charsize == HUGE_SIZE) {
  2525.                 fread(raster_line_buf, 1, (int) nbpl, pxlfp);
  2526.                 sl = raster_line_buf;
  2527.             } else
  2528.                 sl = ((unsigned char *)(ce->where.address.pixptr)
  2529.                     + i * nbpl);
  2530.  
  2531.             RasterLine(ce, (unsigned int)nbpl, i, sl);
  2532.         }
  2533.     } else if (fontptr->id == id1001) {
  2534.         long4    filediff;
  2535.         filediff = (long4)nwpl * 4 - nbpl;
  2536.         for (i = 0; i < (int) ce->height; i++) {
  2537.             if (ce->charsize == HUGE_SIZE) {
  2538.                 fread(raster_line_buf, 1, (int) nbpl, pxlfp);
  2539.                 /* skip fill bytes */
  2540.                 fseek(pxlfp, filediff, 1);
  2541.                 sl = raster_line_buf;
  2542.             } else
  2543.                 sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
  2544.  
  2545.             RasterLine(ce, (unsigned int)nbpl, i, sl);
  2546.         }
  2547.     }
  2548. #else
  2549.     for (i = num_rows; i > 0; i--)
  2550.       RasterLine(ce, (unsigned int)nbpl, i, bits + (i-1) * nbpl);
  2551. #endif
  2552. #ifdef LJ
  2553.     EMIT(outfp, "\033*rB");
  2554. #endif
  2555.     last_ry = UNKNOWN;
  2556. }
  2557.  
  2558.  
  2559. /*-->Fatal*/
  2560. /**********************************************************************/
  2561. /******************************  Fatal  *******************************/
  2562. /**********************************************************************/
  2563. void
  2564. Fatal(fmt, a, b, c)      /* issue a fatal error message */
  2565. char    *fmt;           /* format              */
  2566. char    *a, *b, *c;     /* arguments           */
  2567. {
  2568.     fprintf(stderr, "\n");
  2569.     fprintf(stderr, "%s: FATAL--", G_progname);
  2570.     fprintf(stderr, fmt, a, b, c);
  2571.     fprintf(stderr, "\n\n");
  2572. #ifndef vms
  2573.     exit(2);
  2574. #else
  2575.     exit(SS$_ABORT);
  2576. #endif
  2577. }
  2578.  
  2579.  
  2580. /*-->FindPostAmblePtr*/
  2581. /**********************************************************************/
  2582. /************************  FindPostAmblePtr  **************************/
  2583. /**********************************************************************/
  2584. void
  2585. FindPostAmblePtr(postambleptr)
  2586. long4    *postambleptr;
  2587. /* this routine will move to the end of the file and find the start
  2588.     of the postamble */
  2589. {
  2590.     long4    i;
  2591.     fseek (dvifp,  0l, 2);   /* goto end of file */
  2592.     *postambleptr = ftell (dvifp) - 4;
  2593.     fseek (dvifp, *postambleptr, 0);
  2594.     while (_TRUE) {
  2595.         fseek (dvifp, --(*postambleptr), 0);
  2596.         if (((i = NoSignExtend(dvifp, 1)) != 223) &&
  2597.             (i != DVIFORMAT))
  2598.             Fatal ("Bad end of DVI file");
  2599.         if (i == DVIFORMAT)
  2600.             break;
  2601.     }
  2602.     fseek (dvifp, (*postambleptr) - 4, 0);
  2603.     (*postambleptr) = NoSignExtend(dvifp, 4);
  2604.     fseek (dvifp, *postambleptr, 0);
  2605. }
  2606.  
  2607.  
  2608. /*-->GetBytes*/
  2609. /**********************************************************************/
  2610. /*****************************  GetBytes  *****************************/
  2611. /**********************************************************************/
  2612. void
  2613. GetBytes(fp, cp, n)     /* get n bytes from file fp */
  2614. /*register*/ FILE *fp;      /* file pointer  */
  2615. register char   *cp;    /* character pointer */
  2616. int     n;            /* number of bytes  */
  2617. {
  2618.     while (n--)
  2619.         *cp++ = (char)getc(fp);
  2620. }
  2621.  
  2622.  
  2623. /*-->GetFontDef*/
  2624. /**********************************************************************/
  2625. /**************************** GetFontDef  *****************************/
  2626. /**********************************************************************/
  2627. void
  2628. GetFontDef()
  2629. /***********************************************************************
  2630.    Read the font  definitions as they  are in the  postamble of the  DVI
  2631.    file.
  2632. ***********************************************************************/
  2633. {
  2634.     unsigned char   byte;
  2635.     while (((byte = (unsigned char) NoSignExtend(dvifp, 1)) >= FNT_DEF1) &&
  2636.         (byte <= FNT_DEF4)) {
  2637.         switch (byte) {
  2638.         case FNT_DEF1:
  2639.             ReadFontDef ( NoSignExtend(dvifp, 1));
  2640.             break;
  2641.         case FNT_DEF2:
  2642.             ReadFontDef ( NoSignExtend(dvifp, 2));
  2643.             break;
  2644.         case FNT_DEF3:
  2645.             ReadFontDef ( NoSignExtend(dvifp, 3));
  2646.             break;
  2647.         case FNT_DEF4:
  2648.             ReadFontDef ( NoSignExtend(dvifp, 4));
  2649.             break;
  2650.         default:
  2651.             Fatal ("Bad byte value in font defs");
  2652.             break;
  2653.         }
  2654.     }
  2655.     if (byte != POST_POST)
  2656.         Fatal ("POST_POST missing after fontdefs");
  2657. }
  2658.  
  2659.  
  2660. /*-->GetKeyStr*/
  2661. /**********************************************************************/
  2662. /*****************************  GetKeyStr  ****************************/
  2663. /**********************************************************************/
  2664. /* extract first keyword-value pair from string (value part may be null)
  2665.  * return pointer to remainder of string
  2666.  * return NULL if none found
  2667.  */
  2668. char    KeyStr[STRSIZE];
  2669. char    ValStr[STRSIZE];
  2670. char
  2671. *GetKeyStr( str, kw )
  2672. char    *str;
  2673. KeyWord *kw;
  2674. {
  2675.     char    *s, *k, *v, t;
  2676.     if ( !str )
  2677.         return( NULL );
  2678.     for ( s = str; *s == ' '; s++)
  2679.         ;          /* skip over blanks */
  2680.     if ( *s == '\0' )
  2681.         return( NULL );
  2682.     for ( k = KeyStr; /* extract keyword portion */
  2683.     *s != ' ' && *s != '\0' && *s != '=';
  2684.         *k++ = *s++)
  2685.         ;
  2686.     *k = '\0';
  2687.     kw->Key = KeyStr;
  2688.     kw->Val = v = NULL;
  2689.     kw->vt = None;
  2690.     for ( ; *s == ' '; s++)
  2691.         ;            /* skip over blanks */
  2692.     if ( *s != '=' )         /* look for "=" */
  2693.         return( s );
  2694.     for ( s++; *s == ' '; s++);      /* skip over blanks */
  2695.     if ( *s == '\'' || *s == '\"' )  /* get string delimiter */
  2696.         t = *s++;
  2697.     else
  2698.         t = ' ';
  2699.     for ( v = ValStr; /* copy value portion up to delim */
  2700.     *s != t && *s != '\0';
  2701.         *v++ = *s++)
  2702.         ;
  2703.     if ( t != ' ' && *s == t )
  2704.         s++;
  2705.     *v = '\0';
  2706.     kw->Val = ValStr;
  2707.     kw->vt = String;
  2708.     return( s );
  2709. }
  2710.  
  2711.  
  2712. /*-->GetKeyVal*/
  2713. /**********************************************************************/
  2714. /*****************************  GetKeyVal  ****************************/
  2715. /**********************************************************************/
  2716. /* get next keyword-value pair decode value according to table entry  */
  2717. bool
  2718. GetKeyVal( kw, tab, nt, tno)
  2719. KeyWord *kw;
  2720. KeyDesc tab[];
  2721. int     nt;
  2722. int     *tno;
  2723. {
  2724.     int     i;
  2725.     char    c = '\0';
  2726.     *tno = -1;
  2727.     for (i = 0; i < nt; i++)
  2728.         if ( IsSame(kw->Key, tab[i].Entry) ) {
  2729.             *tno = i;
  2730.             switch ( tab[i].Typ ) {
  2731.             case None:
  2732.                 if ( kw->vt != None )
  2733.                     return( _FALSE );
  2734.                 break;
  2735.             case String:
  2736.                 if ( kw->vt != String )
  2737.                     return( _FALSE );
  2738.                 break;
  2739.             case Integer:
  2740.                 if ( kw->vt != String )
  2741.                     return( _FALSE );
  2742.                 if ( sscanf(kw->Val, "%d%c",
  2743.                     &(kw->v.i), &c) != 1
  2744.                      || c != '\0' )
  2745.                     return( _FALSE );
  2746.                 break;
  2747. /*              case Number:
  2748.  *              case Dimension:
  2749.  *                  if( kw->vt != String ) return( _FALSE );
  2750.  *                  if( sscanf(kw->Val,"%f%c",
  2751.  *                     &(kw->v.n), &c) != 1
  2752.  *                  || c != '\0' ) return( _FALSE );
  2753.  *                  break;
  2754.  */
  2755.             }
  2756.             kw->vt = tab[i].Typ;
  2757.             return( _TRUE );
  2758.         }
  2759.     return( _TRUE );
  2760. }
  2761.  
  2762.  
  2763.  
  2764. /*-->IsSame*/
  2765. /**********************************************************************/
  2766. /*******************************  IsSame  *****************************/
  2767. /**********************************************************************/
  2768. bool                  /* compare strings, ignore case */
  2769. IsSame(a, b)
  2770. char    *a, *b;
  2771. {
  2772.     char *x, *y;
  2773.     x = a;
  2774.     y = b;
  2775.     for ( ; *a != '\0'; a++,b++)
  2776.         if ( tolower(*a) != tolower(*b) )
  2777.             return( _FALSE );
  2778.     return( *x == *y ? _TRUE : _FALSE );
  2779. }
  2780.  
  2781.  
  2782. /*-->NoSignExtend*/
  2783. /**********************************************************************/
  2784. /***************************  NoSignExtend  ***************************/
  2785. /**********************************************************************/
  2786. long4
  2787. NoSignExtend(fp, n)     /* return n byte quantity from file fd */
  2788. register FILE *fp;      /* file pointer    */
  2789. register int    n;      /* number of bytes */
  2790. {
  2791.     long4    x;      /* number being constructed */
  2792.     x = 0;
  2793.     while (n--)  {
  2794.         x <<= 8;
  2795.         x |= getc(fp);
  2796.     }
  2797.     return(x);
  2798. }
  2799.  
  2800.  
  2801. /*-->OpenFontFile*/
  2802. /**********************************************************************/
  2803. /************************** OpenFontFile  *****************************/
  2804. /**********************************************************************/
  2805. void
  2806. OpenFontFile()
  2807. /***********************************************************************
  2808.     The original version of this dvi driver reopened the font file  each
  2809.     time the font changed, resulting in an enormous number of relatively
  2810.     expensive file  openings.   This version  keeps  a cache  of  up  to
  2811.     MAXOPEN open files,  so that when  a font change  is made, the  file
  2812.     pointer, pxlfp, can  usually be  updated from the  cache.  When  the
  2813.     file is not found in  the cache, it must  be opened.  In this  case,
  2814.     the next empty slot  in the cache  is assigned, or  if the cache  is
  2815.     full, the least used font file is closed and its slot reassigned for
  2816.     the new file.  Identification of the least used file is based on the
  2817.     counts of the number  of times each file  has been "opened" by  this
  2818.     routine.  On return, the file pointer is always repositioned to  the
  2819.     beginning of the file.
  2820. ***********************************************************************/
  2821. {
  2822.     int     i, least_used, current;
  2823.     struct pixel_list tmp;
  2824.  
  2825. #ifdef DEBUG
  2826.     if (Debug)
  2827.         fprintf(stderr,"open font file %p\n", fontptr->font_file_id);
  2828. #endif
  2829. /*
  2830. fprintf(stderr,"? %lx == %lx\n", pfontptr,fontptr);
  2831. */
  2832.     if ((pfontptr == fontptr) && (pxlfp != NO_FILE))
  2833.         return;         /* we need not have been called */
  2834.  
  2835.        if (fontptr->font_file_id == NO_FILE)
  2836.         return;         /* we need not have been called */
  2837.  
  2838.     tmp = pixel_files[1];
  2839.     for (current = 1;
  2840.         (current <= nopen) && (tmp.pixel_file_id != fontptr->font_file_id); ) {
  2841.         ++current;
  2842.         tmp = pixel_files[current];
  2843.     }
  2844.     /* try to find file in open list */
  2845.  
  2846.     if (current <= nopen)       /* file already open */ {
  2847.         if ( (pxlfp = pixel_files[current].pixel_file_id) != NO_FILE )
  2848.             fseek(pxlfp, 0l, 0);
  2849.             /* reposition to start of file */
  2850.     } else {
  2851.             /* file not in open list          */
  2852.         if (nopen < MAXOPEN)    /* just add it to list    */
  2853.             current = ++nopen;
  2854.         else  {
  2855.             /* list full -- find least used file,     */
  2856.             /* close it, and reuse slot for new file  */
  2857.             least_used = 1;
  2858.             for (i = 2; i <= MAXOPEN; ++i)
  2859.                 if (pixel_files[least_used].use_count>pixel_files[i].use_count)
  2860.                     least_used = i;
  2861.             if (pixel_files[least_used].pixel_file_id != NO_FILE) {
  2862.                 FILE * fid;
  2863.                 struct font_entry *fp;
  2864.                 fid = pixel_files[least_used].pixel_file_id;
  2865.                 /* mark file as being closed in the entry */
  2866.                 fp = hfontptr;
  2867.                 while (fp != NULL && fp->font_file_id != fid) fp = fp->next;
  2868.                 if (fp == NULL)
  2869.                    Fatal("Open file %x not found in font entry list.\n", fid);
  2870.                 else {
  2871.                     fp->font_file_id = NULL;
  2872.                 }
  2873.                 fclose( fid );
  2874.             }
  2875. #ifdef DEBUG
  2876.             if (Debug)
  2877.                  fprintf(stderr,"\n__reuse slot %d\n", least_used);
  2878. #endif
  2879.             current = least_used;
  2880.         }
  2881.         if ((pxlfp = BINOPEN(fontptr->name)) == NULL) {
  2882.             Warning("PXL-file %s could not be opened", fontptr->name);
  2883.             pxlfp = NO_FILE;
  2884.         } else {
  2885. #ifdef DEBUG
  2886.              if (Debug) 
  2887.            fprintf(stderr,"Opening File  <%s> /%p/, Size(font_entry)=%d\n",
  2888.                fontptr->name, pxlfp, sizeof(struct font_entry ));
  2889. #endif
  2890.  
  2891.         }
  2892.         pixel_files[current].pixel_file_id = pxlfp;
  2893.         pixel_files[current].use_count = 0;
  2894.     }
  2895.     pfontptr = fontptr;         /* make previous = current font */
  2896.     fontptr->font_file_id = pxlfp;      /* set file identifier */
  2897.     pixel_files[current].use_count++;   /* update reference count */
  2898. #ifndef USEPXL
  2899.     gfin = pxlfp;
  2900. #endif
  2901. }
  2902.  
  2903.  
  2904. /*-->PixRound*/
  2905. /**********************************************************************/
  2906. /*****************************  PixRound  *****************************/
  2907. /**********************************************************************/
  2908. long4
  2909. PixRound(x, conv)       /* return rounded number of pixels */
  2910. long4    x;          /* in DVI units     */
  2911. long4    conv;       /* conversion factor */
  2912. {
  2913.     return((x + conv) / conv);
  2914. }
  2915.  
  2916. #ifdef LJ_RESIDENT_FONTS
  2917. /*-->TryResident*/
  2918. /**********************************************************************/
  2919. /****************************  TryResident  ***************************/
  2920. /**********************************************************************/
  2921. bool
  2922. TryResident(fontptr)
  2923. struct font_entry *fontptr;
  2924. {
  2925.   extern bool tfm_read_info ();
  2926.   tfm_info_type tfm_info;
  2927.   
  2928.   /* To determine if a font is resident, check for a special family
  2929.      value (header bytes 12..16 in the TFM file). This seems cleaner,
  2930.      and certainly more convenient, than somehow reading an external
  2931.      ljfonts.map file in which we'd have to specify information for all
  2932.      the resident fonts.  */
  2933.   if (tfm_read_info (fontptr->n, &tfm_info)
  2934.       && tfm_info.family[0]
  2935.       && strcmp (tfm_info.family, "HPAUTOTFM") == 0) {
  2936.     unsigned i;
  2937.     double factor = fontptr->s / (double) 0x100000;
  2938.  
  2939.     resident_count++;
  2940.     fontptr->resident_p = _TRUE;
  2941.     strcpy (fontptr->symbol_set, tfm_info.coding_scheme);
  2942.     fontptr->resid = tfm_info.typeface_id;
  2943.     fontptr->spacing = tfm_info.spacing;
  2944.     fontptr->style = tfm_info.style;
  2945.     fontptr->weight = tfm_info.weight;
  2946.  
  2947.     if (fontptr->spacing == SPACING_FIXED) {
  2948.       /* Have to select the point in pitch (characters per inch) instead
  2949.          of point size, and thus have to figure out the pitch that
  2950.          corresponds to the point size at which the font is used.
  2951.          
  2952.          To do this, take the width of the interword space, and see how
  2953.          many of those characters will fit in the at size. Then convert
  2954.          to how many characters will fit in one inch. That's our pitch.
  2955.          
  2956.          All the builtin LJ4 fonts that are monospaced are Intellifont,
  2957.          which have 72.307 points per inch. Not that it really makes any
  2958.          difference. We don't worry about this elsewhere, since all
  2959.          point sizes are rounded to .25pt anyway, which is more than the
  2960.          difference between the various definitions of `point'. */
  2961.       double ds_in_points = fontptr->s / 65536.0;
  2962.       double w_in_points = tfm_info.interword / (double) 0x100000;
  2963.       if (ds_in_points == 0 || w_in_points == 0) {
  2964.         /* Avoid division by zero if no interword space. */
  2965.         Warning ("%s: Can't determine pitch for this monospaced font.\n", 
  2966.                  fontptr->n);
  2967.         fontptr->pitch = 10; /* Result will look awful, which is good. */
  2968.       } else {
  2969.         fontptr->pitch = 72.307 / (ds_in_points * w_in_points);
  2970.       }
  2971.     }
  2972.     
  2973. #ifdef DEBUG
  2974.     if (Debug)
  2975.       fprintf(stderr, "%6s: typeface=%u\tspacing=%u\tstyle=%u\tweight=%d\n",
  2976.               fontptr->n, fontptr->resid, fontptr->spacing,
  2977.               fontptr->style, fontptr->weight);
  2978. #endif
  2979.     for (i = 0; i < NFNTCHARS; i++) {
  2980.       struct char_entry *cptr = &(fontptr->ch[i]);
  2981.       cptr->tfmw = (long4) (tfm_info.widths[i] * factor);
  2982.       cptr->cw = ((fontptr->ch[i].tfmw) / (double) hconv) + .5;
  2983.       cptr->width = 
  2984.     cptr->height = 
  2985.       cptr->xOffset = 
  2986.         cptr->yOffset = 
  2987.           cptr->yyOffset = 0;
  2988.     }
  2989.     return _TRUE;
  2990.   } else {
  2991.     fontptr->resident_p = _FALSE;
  2992.  
  2993.     if (tfm_info.family[0]
  2994.     && strcmp (tfm_info.family, "UNSPECIFIED") == 0) {
  2995.       Warning("font family for %s is UNSPECIFIED; need to run dvicopy?",
  2996.           fontptr->n);
  2997.       fontptr->font_file_id = NO_FILE;
  2998.       return _TRUE;
  2999.     } else {
  3000.       return _FALSE;
  3001.     }
  3002.   }
  3003. }
  3004. #endif
  3005.  
  3006.  
  3007.  
  3008. /*-->ReadFontDef*/
  3009. /**********************************************************************/
  3010. /****************************  ReadFontDef  ***************************/
  3011. /**********************************************************************/
  3012. void
  3013. ReadFontDef(k)
  3014. long4    k;
  3015. {
  3016.     long4    t;
  3017.     unsigned short i;
  3018.     struct font_entry *tfontptr; /* temporary font_entry pointer   */
  3019.     struct char_entry *tcharptr; /* temporary char_entry pointer  */
  3020.     static int      plusid = 0;
  3021.     bool font_found = _FALSE;
  3022. #ifdef LJ_RESIDENT_FONTS
  3023.     bool resident_font_located = _FALSE;
  3024. #endif
  3025. #ifdef LJ
  3026.     int depth, max_depth;
  3027. #endif
  3028.  
  3029. #ifdef DEBUG
  3030.     if (Debug)
  3031.       fprintf(stderr,"Mallocating %d Bytes)...\n", sizeof(struct font_entry ));
  3032. #endif
  3033.  
  3034.     if ((tfontptr = NEW(struct font_entry )) == NULL)
  3035.         Fatal("can't malloc space for font_entry");
  3036.  
  3037.     allocated_storage += sizeof(struct font_entry );
  3038.  
  3039.     tfontptr->next = hfontptr;
  3040.     tfontptr->font_file_id = NULL;
  3041.     fontptr = hfontptr = tfontptr;
  3042.     tfontptr->ncdl = 0;
  3043.     tfontptr->k = k;
  3044.     tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */
  3045.     tfontptr->s = NoSignExtend(dvifp, 4); /* space size */
  3046.     tfontptr->d = NoSignExtend(dvifp, 4); /* design size */
  3047.     tfontptr->a = (int) NoSignExtend(dvifp, 1); /* length for font name */
  3048.     tfontptr->l = (int) NoSignExtend(dvifp, 1); /* device length */
  3049.  
  3050. #ifdef LJ
  3051.     tfontptr->max_width = tfontptr->max_height = tfontptr->max_yoff =
  3052.                           max_depth = 0;
  3053. #endif
  3054.  
  3055.     GetBytes(dvifp, tfontptr->n, tfontptr->a + tfontptr->l);
  3056.     tfontptr->n[tfontptr->a+tfontptr->l] = '\0';
  3057.  
  3058.     tfontptr->font_mag = (long4)((
  3059.          ActualFactor((long4)(1000.0*tfontptr->s/(double)tfontptr->d+0.5))
  3060.          * ActualFactor(mag)
  3061. #ifdef USEPXL
  3062.          * RESOLUTION * 5.0
  3063. #else
  3064.          * RESOLUTION
  3065. #endif
  3066.            ) + 0.5);
  3067. /*
  3068. printf("[%ld]=%lf * %lf * %lf + 0.5 = %ld\n",
  3069.     ((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
  3070.     ActualFactor((long4)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
  3071.     ActualFactor(mag),
  3072.     (double)RESOLUTION * 5,
  3073.     (long)tfontptr->font_mag );
  3074. */
  3075.  
  3076. #ifdef LJ_RESIDENT_FONTS
  3077.     /* Pass in the name; fills in resident_p and resid (if resident). */
  3078.  
  3079.     resident_font_located = (bool) TryResident(tfontptr);
  3080.     
  3081.     if (tfontptr->resident_p)
  3082.       return;
  3083.  
  3084.     if (!(resident_font_located)) {
  3085. #endif
  3086.  
  3087. #ifdef KPATHSEA
  3088.     {
  3089.       kpse_glyph_file_type font_ret;
  3090.       char *name;
  3091.       unsigned dpi
  3092.         = kpse_magstep_fix ((unsigned) (tfontptr->font_mag / 5.0 + .5),
  3093.                             RESOLUTION, NULL);
  3094.       tfontptr->font_mag = dpi * 5; /* save correct dpi */
  3095.       
  3096.       name = kpse_find_pk (tfontptr->n, dpi, &font_ret);
  3097.       if (name)
  3098.         {
  3099.           font_found = _TRUE;
  3100.           strcpy (tfontptr->name, name);
  3101.           free (name);
  3102.           
  3103.           if (!STREQ (tfontptr->n, font_ret.name)) {
  3104.               fprintf (stderr,
  3105.                        "dvilj: Font %s not found, using %s at %d instead.\n",
  3106.                        tfontptr->n, font_ret.name, font_ret.dpi);
  3107.               tfontptr->c = 0; /* no checksum warning */
  3108.             }
  3109.           else if (!kpse_bitmap_tolerance ((double)font_ret.dpi, (double) dpi))
  3110.             fprintf (stderr,
  3111.                      "dvilj: Font %s at %d not found, using %d instead.\n",
  3112.                      tfontptr->name, dpi, font_ret.dpi);
  3113.           if (!( (G_noverbatim) || (G_quiet) ) )
  3114.             fprintf(stderr,"%d: using font <%s>\n", plusid,tfontptr->name);
  3115.         }
  3116.       else
  3117.         {
  3118.           tfontptr->font_file_id = NO_FILE;
  3119.           fprintf (stderr,
  3120.             "dvilj: Font %s at %u not found, characters will be left blank.\n",
  3121.             tfontptr->n, dpi);
  3122.         }
  3123.     }
  3124. #else /* not KPATHSEA */
  3125.       if (!(findfile(PXLpath, 
  3126.              tfontptr->n, 
  3127.              tfontptr->font_mag, 
  3128.              tfontptr->name,
  3129.              _FALSE,
  3130.              0))) {
  3131.     Warning(tfontptr->name); /* contains error messsage */
  3132.     tfontptr->font_file_id = NO_FILE;
  3133.       }
  3134.       else {
  3135.     font_found = TRUE;
  3136.     if (!( (G_noverbatim) || (G_quiet) ) )
  3137.       fprintf(stderr,"%d: using font <%s>\n",
  3138.           plusid,tfontptr->name);
  3139.       }
  3140. #endif /* not KPATHSEA */
  3141.  
  3142. #ifdef LJ_RESIDENT_FONTS
  3143.     }
  3144. #endif
  3145.  
  3146.     tfontptr->plusid = plusid;
  3147.     plusid++;
  3148.  
  3149.     /* sprintf(tfontptr->psname,"%s.%ld.%d",
  3150.        tfontptr->n,(long)tfontptr->font_mag,tfontptr->plusid);*/
  3151.  
  3152. #ifdef LJ
  3153.     if (plusid >= HANDLE_MAX_FONTS)
  3154.         Fatal("can handle only %d fonts! ask a wizzard...\n",
  3155.                HANDLE_MAX_FONTS);
  3156. #endif
  3157.     if (tfontptr != pfontptr) {
  3158.         if (font_found) OpenFontFile();
  3159.         else
  3160.             pxlfp = NO_FILE;
  3161.     }
  3162. #ifdef USEPXL
  3163.     if ( pxlfp == NO_FILE ) {        /* allow missing pxl files */
  3164.         tfontptr->magnification = 0;
  3165.         tfontptr->designsize = 0;
  3166. #endif
  3167.         for (i = FIRSTFNTCHAR; i <= LASTFNTCHAR; i++) {
  3168.             tcharptr = &(tfontptr->ch[i]);
  3169. #ifdef USEPXL
  3170.             tcharptr->width = 0;
  3171.             tcharptr->height = 0;
  3172.             tcharptr->xOffset = 0;
  3173.             tcharptr->yOffset = 0;
  3174. #endif
  3175.             tcharptr->where.isloaded = _FALSE;
  3176.             tcharptr->where.address.fileOffset = NONEXISTANT;
  3177.             tcharptr->tfmw = 0;
  3178.         }
  3179. #ifdef USEPXL
  3180.         return;
  3181.     }
  3182.     t = (long4) NoSignExtend(pxlfp, 1);
  3183.     if (t == 0) {
  3184.         t = (long4) NoSignExtend(pxlfp, 1);
  3185.         t = (long4) NoSignExtend(pxlfp, 2);
  3186.         if (t == 1002)
  3187.             tfontptr->id = id1002;
  3188.         else if (t == 1001)
  3189.             tfontptr->id = id1001;
  3190.         else
  3191.             Fatal("Unknown Version of PXL-format\n");
  3192.     } else {
  3193.         if (t == PK_PRE)    {
  3194.             unsigned char   temp_byte;
  3195.             temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  3196.             if (temp_byte != PK_ID) Fatal(
  3197.                "Wrong Version of pk file!  (%d should be 89)\n",
  3198.                              (int)temp_byte);
  3199.             else
  3200.                 tfontptr->id = pk89;
  3201.         } else
  3202.             Fatal("unknown font format in file <%s> !\n",fontptr->name);
  3203.     }
  3204.  
  3205.     if ((tfontptr->id == id1002) || (tfontptr->id == id1001)) {
  3206.         fseek(pxlfp, -20l, 2);
  3207.  
  3208.         t = NoSignExtend(pxlfp, 4);
  3209.         if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
  3210.     Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX",
  3211.                           tfontptr->name, tfontptr->c, t);
  3212.         tfontptr->magnification = NoSignExtend(pxlfp, 4);
  3213.         tfontptr->designsize    = NoSignExtend(pxlfp, 4);
  3214.  
  3215.         if (tfontptr->id == id1001)
  3216.             fseek(pxlfp, (long) (NoSignExtend(pxlfp, 4) * 4), 0);
  3217.         else
  3218.             fseek(pxlfp, (long) NoSignExtend(pxlfp, 4) , 0);
  3219.  
  3220.         for (i = FIRSTFNTCHAR; i <= 127; i++) {   /* only defined for 7bit*/
  3221.             tcharptr = &(tfontptr->ch[i]);
  3222.             tcharptr->width   = (unsigned short) NoSignExtend(pxlfp, 2);
  3223.             tcharptr->height  = (unsigned short) NoSignExtend(pxlfp, 2);
  3224.             tcharptr->xOffset = (short) SignExtend(pxlfp, 2);
  3225.             tcharptr->yOffset = (short) SignExtend(pxlfp, 2);
  3226.             tcharptr->where.isloaded = _FALSE;
  3227.             if (tfontptr->id == id1001)
  3228.                 tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4) * 4;
  3229.             else
  3230.                 tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4);
  3231.             tcharptr->tfmw = (long4)
  3232.             (   (double)(NoSignExtend(pxlfp, 4))
  3233.               * (double)tfontptr->s / (double) 0x100000 );
  3234.             tcharptr->cw = (long4)(((double)tcharptr->tfmw/(double)hconv) + 0.5);
  3235.  
  3236.             if (tcharptr->width  > CHAR_WIDTH_LARGE  ||
  3237.                 tcharptr->height > CHAR_HEIGTH_LARGE )
  3238.                 tcharptr->charsize = LARGE_SIZE;
  3239.             else
  3240.                 tcharptr->charsize = SMALL_SIZE;
  3241. #ifdef LJ
  3242.             max(tfontptr->max_width,tcharptr->width);
  3243.             max(tfontptr->max_height,tcharptr->height);
  3244.             if (tcharptr->yOffset > 0  && (int)tfontptr->max_yoff < (int)tcharptr->yOffset) 
  3245.           tfontptr->max_yoff = tcharptr->yOffset;
  3246.             if ((depth = tcharptr->height - tcharptr->yOffset)>max_depth)
  3247.                    max_depth = depth;
  3248. #endif
  3249.  
  3250.         }
  3251. #ifdef LJ
  3252.         tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
  3253.                                            tfontptr->max_yoff+1;
  3254. #endif
  3255.     } else { /* PK 89 format */
  3256.         unsigned char   temp_byte;
  3257.         register unsigned char  flag_byte;
  3258.         long4    hppp, vppp, pkloc, packet_length;
  3259.         int     car, ii;
  3260.  
  3261.         /* read comment */
  3262.         for ( ii = temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  3263.               ii>0; ii--) {
  3264.             flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  3265. #ifdef DEBUG
  3266.             if (Debug) fprintf(stderr, "%c", flag_byte ) ;
  3267. #endif
  3268.         }
  3269. #ifdef DEBUG
  3270.         if (Debug) fprintf(stderr, "\n");
  3271. #endif
  3272.         pkloc = 3 + (int)temp_byte;
  3273.         tfontptr->designsize = NoSignExtend(pxlfp, 4);
  3274.  
  3275.         t = NoSignExtend(pxlfp, 4);
  3276.         if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
  3277.           Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX",
  3278.                  tfontptr->name, tfontptr->c, t);
  3279.  
  3280.         hppp = NoSignExtend(pxlfp, 4);
  3281.         vppp = NoSignExtend(pxlfp, 4);
  3282.         if (hppp != vppp)
  3283.             Warning("aspect ratio is %ld:%ld (should be 1:1)!", (long)hppp,(long)vppp);
  3284.         tfontptr->magnification = (long4)(hppp * 72.27 * 5 / 65536l + 0.5);
  3285.  
  3286.         pkloc += 16;
  3287.         flag_byte = skip_specials(&pkloc);
  3288.  
  3289.         while (flag_byte != PK_POST) {
  3290.         if ((flag_byte & 7) == 7) {
  3291.         /* fprintf(stderr,"\nRead long character preamble\n"); */
  3292.  
  3293.            packet_length = (unsigned long4)NoSignExtend(pxlfp,4);
  3294.            if ((car = (int)NoSignExtend(pxlfp, 4)) > (LASTFNTCHAR))
  3295.                 Fatal("Bad character (%d) in PK-File\n",(int)car) ;
  3296.  
  3297.            tcharptr = &(tfontptr->ch[car]);
  3298.            tcharptr->where.address.fileOffset = pkloc;
  3299.            /* set pkloc to end_of_packet */
  3300.            pkloc += packet_length + 8;
  3301.  
  3302.            tcharptr->tfmw = (long4) NoSignExtend(pxlfp, 4);
  3303.            (void) NoSignExtend(pxlfp, 4); /* horesc not used */
  3304.            (void) NoSignExtend(pxlfp, 4); /* not used */
  3305.  
  3306.            tcharptr ->width   = (unsigned short) NoSignExtend(pxlfp, 4);
  3307.            tcharptr ->height  = (unsigned short) NoSignExtend(pxlfp, 4);
  3308.            tcharptr ->xOffset = (short) SignExtend(pxlfp, 4);
  3309.            tcharptr ->yOffset = (short) SignExtend(pxlfp, 4);
  3310.            tcharptr ->where.isloaded = _FALSE;
  3311.         } else if (flag_byte & 4) {
  3312.             /* fprintf(stderr,"Read extended short character preamble\n"); */
  3313.  
  3314.             packet_length = ((long4) flag_byte & 3) * 65536l +
  3315.                 (unsigned short) NoSignExtend(pxlfp, 2);
  3316.             if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
  3317.                 Fatal("Bad character (%d) in PK-File\n",(int)car) ;
  3318.  
  3319.             tcharptr = &(tfontptr->ch[car]);
  3320.             tcharptr->where.address.fileOffset = pkloc;
  3321.             /* set pkloc to end_of_packet */
  3322.             pkloc += packet_length + 3;
  3323.  
  3324.             tcharptr->tfmw = (long4) NoSignExtend(pxlfp, 3);
  3325. /*
  3326.             { register unsigned short t;
  3327.               t = (unsigned short) NoSignExtend(pxlfp, 1);
  3328.               tcharptr->tfmw = t * 65536l +
  3329.               (unsigned short) NoSignExtend(pxlfp, 2);
  3330.             }
  3331. */
  3332.             /* horesc not used */
  3333.             (void) NoSignExtend(pxlfp, 2) ;
  3334.             tcharptr ->width   = (unsigned short) NoSignExtend(pxlfp,2);
  3335.             tcharptr ->height  = (unsigned short) NoSignExtend(pxlfp,2);
  3336.             tcharptr ->xOffset = (short) SignExtend(pxlfp, 2);
  3337.             tcharptr ->yOffset = (short) SignExtend(pxlfp, 2);
  3338.             tcharptr ->where.isloaded = _FALSE;
  3339.         } else {
  3340.             /* fprintf(stderr,"<Read short character preamble@>\n"); */
  3341.  
  3342.             packet_length = ((long4)flag_byte & 3) * 256 +
  3343.                 NoSignExtend(pxlfp, 1) ;
  3344.             if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
  3345.                 Fatal("Bad character (%d) in PK-File\n",(int)car) ;
  3346.  
  3347.             tcharptr = &(tfontptr->ch[car]);
  3348.             tcharptr->where.address.fileOffset = pkloc;
  3349.             /* set pkloc to end_of_packet */
  3350.             pkloc += packet_length + 2 ;
  3351.  
  3352.             tcharptr->tfmw = (long4) NoSignExtend(pxlfp, 3);
  3353. /*
  3354.             { register unsigned short t;
  3355.               t = (unsigned short) NoSignExtend(pxlfp, 1);
  3356.               tcharptr->tfmw = t * 65536l +
  3357.               (unsigned short) NoSignExtend(pxlfp, 2);
  3358.             }
  3359. */
  3360.             /* horesc not used */
  3361.             (void) NoSignExtend(pxlfp, 1) ;
  3362.             tcharptr ->width   = (unsigned short) NoSignExtend(pxlfp,1);
  3363.             tcharptr ->height  = (unsigned short) NoSignExtend(pxlfp,1);
  3364.             tcharptr ->xOffset = (short) SignExtend(pxlfp, 1);
  3365.             tcharptr ->yOffset = (short) SignExtend(pxlfp, 1);
  3366.             tcharptr ->where.isloaded = _FALSE;
  3367.         }
  3368.  
  3369.         tcharptr->tfmw = (long4)
  3370.            ( tcharptr->tfmw * (double)tfontptr->s / (double) 0x100000 );
  3371.  
  3372.         tcharptr->cw = (long4)(((double)tcharptr->tfmw /
  3373.             (double)hconv) + 0.5);
  3374.  
  3375.         if (tcharptr->width  > CHAR_WIDTH_LARGE  ||
  3376.             tcharptr->height > CHAR_HEIGTH_LARGE )
  3377.             tcharptr->charsize = LARGE_SIZE;
  3378.         else
  3379.             tcharptr->charsize = SMALL_SIZE;
  3380.  
  3381. #ifdef LJ
  3382. /*
  3383. printf("char=%d: this=%d, max_width=%d, this=%d,max_height=%d, this=%d,max_yoff=%d\n",
  3384.        car, tcharptr->width, tfontptr->max_width,
  3385.        tcharptr->height,tfontptr->max_height, 
  3386.        tcharptr->yOffset,tfontptr->max_yoff);
  3387. */
  3388.         max(tfontptr->max_width, tcharptr->width);
  3389.         max(tfontptr->max_height,tcharptr->height);
  3390.     if (tcharptr->yOffset > 0  && (int)tfontptr->max_yoff < (int)tcharptr->yOffset)
  3391.       tfontptr->max_yoff = tcharptr->yOffset;
  3392.  
  3393.         if ((depth = tcharptr->height - tcharptr->yOffset) > max_depth)
  3394.       max_depth = depth;
  3395. #endif
  3396. /*
  3397. fprintf(stderr,"char=%d, yotcharptr=%lx, flag_byte=%d, font=%lx\n",car, tcharptr,flag_byte,tfontptr);
  3398. */
  3399.         tcharptr->flag_byte = flag_byte;
  3400.         fseek(pxlfp, (long) pkloc, 0);
  3401.         flag_byte = skip_specials(&pkloc);
  3402.  
  3403.         } /* end of while */
  3404. #ifdef LJ
  3405. tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
  3406.                                    tfontptr->max_yoff+1;
  3407. #endif
  3408.  
  3409. /*
  3410. printf("fontid=%d: max_width=%u, max_height=%d, max_yoff=%u\n",
  3411.         tfontptr->plusid, tfontptr->max_width,
  3412.         tfontptr->max_height, tfontptr->max_yoff);
  3413. */
  3414.  
  3415. #else
  3416.     if ( pxlfp == NO_FILE )        /* allow missing pxl files */
  3417.     return;
  3418.  
  3419.     gfin = pxlfp;
  3420.     seekpost();
  3421.     readpost();
  3422.     if ((tfontptr->c != 0) && (checksum != 0) && (tfontptr->c != checksum))
  3423.     Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d",
  3424.         tfontptr->name, tfontptr->c, checksum);
  3425.  
  3426.     for(i=FIRSTFNTCHAR; i<=LASTFNTCHAR; i++) {
  3427.     if (char_exists[i]) {
  3428.         tcharptr = &(tfontptr->ch[i]);
  3429.         tcharptr->tfmw = (long4)(((float)tfm_wd[i]*(float)tfontptr->s) /
  3430.            (float)((long4)1l<<20));
  3431.         tcharptr->where.address.fileOffset = char_pointer[i];
  3432.       }
  3433. #ifdef LJ
  3434. /*                 GF USER PLEASE CHECK IF THIS CODE WORKS
  3435.     tfontptr->max_width = gf_font_max_m;
  3436.     tfontptr->max_height = gf_font_max_n;
  3437.     tfontptr->max_yoff = gf_font_min_n;
  3438. */
  3439. #endif
  3440. #endif
  3441. /*****************************************************************************/
  3442. /*if (tcharptr->charsize==LARGE_SIZE)                                        
  3443.      fprintf(stderr,"%d:\t <%c> w=%d h=%d xO=%d yO=%d tfmw=%ld cw=%ld %d\n",       
  3444.      i,(char) i,                                                          
  3445.      tcharptr->width,tcharptr->height,tcharptr->xOffset,tcharptr->yOffset,
  3446.      (long)tcharptr->tfmw, (long)tcharptr->cw, (int)(tcharptr->charsize));           
  3447.  */
  3448. /*****************************************************************************/
  3449.     }
  3450.   }
  3451.  
  3452.  
  3453. unsigned char
  3454. skip_specials( pkloc )
  3455. long4    *pkloc;
  3456. {
  3457.     long4    i, j;
  3458.     register unsigned char  flag_byte;
  3459.     do {
  3460.     flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  3461. /*
  3462. fprintf(stderr,"flagbyte = %d, pkloc=%ld\n",(int)flag_byte,(long)*pkloc);
  3463. */
  3464.  
  3465.     (*pkloc) ++;
  3466.     if (flag_byte  >= 240)
  3467.         switch (flag_byte) {
  3468.         case 240:
  3469.         case 241:
  3470.         case 242:
  3471.         case 243 : {
  3472.             i = 0 ;
  3473.             for (j = 240; j <= (long4)flag_byte; j++) {
  3474.                 i = 256 * i + NoSignExtend(pxlfp, 1) ;
  3475.                 (*pkloc) ++;
  3476.             }
  3477.             for (j = 1; j <= i; j++) {
  3478.                 (void) NoSignExtend(pxlfp, 1) ;
  3479.                 (*pkloc) ++;
  3480.             }
  3481.             break;
  3482.         }
  3483.         case 244 : {
  3484.             i = NoSignExtend(pxlfp, 4);
  3485.             (*pkloc) += 4;
  3486.             break;
  3487.         }
  3488.         case 245 :
  3489.             break;
  3490.         case 246 :
  3491.             break ;
  3492.         case 247:
  3493.         case 248:
  3494.         case 249:
  3495.         case 250:
  3496.         case 251:
  3497.         case 252:
  3498.         case 253:
  3499.         case 254:
  3500.         case 255: {
  3501.             Fatal("Unexpected flagbyte %d!\n",
  3502.                  (int)flag_byte) ;
  3503.             }
  3504.         }
  3505.     } while (!((flag_byte < 240) || (flag_byte == PK_POST))) ;
  3506.     return(flag_byte);
  3507. }
  3508.  
  3509.  
  3510. /*-->ReadPostAmble*/
  3511. /**********************************************************************/
  3512. /**************************  ReadPostAmble  ***************************/
  3513. /**********************************************************************/
  3514. /***********************************************************************
  3515.     This  routine  is  used  to  read  in  the  postamble  values.    It
  3516.     initializes the magnification and checks  the stack height prior  to
  3517.     starting printing the document.
  3518. ***********************************************************************/
  3519. void
  3520. ReadPostAmble(load)
  3521. bool load;
  3522. {
  3523.     FindPostAmblePtr (&postambleptr);
  3524.     if (NoSignExtend(dvifp, 1) != POST)
  3525.         Fatal ("POST missing at head of postamble");
  3526. #ifdef DEBUG
  3527.     if (Debug)
  3528.         fprintf(stderr,"got POST command\n");
  3529. #endif
  3530.     ppagep = NoSignExtend(dvifp, 4);
  3531.     num = NoSignExtend(dvifp, 4);
  3532.     den = NoSignExtend(dvifp, 4);
  3533.     mag = NoSignExtend(dvifp, 4);
  3534.     if ( usermag > 0 && usermag != mag )
  3535.         Warning("DVI magnification of %ld over-ridden by user (%ld)",
  3536.                      (long)mag, (long)usermag );
  3537.     if ( usermag > 0 )
  3538.         mag = usermag;
  3539.     hconv = DoConv(num, den, hconvRESOLUTION);
  3540.     vconv = DoConv(num, den, vconvRESOLUTION);
  3541.     (void) NoSignExtend(dvifp, 4);   /* height-plus-depth of tallest page */
  3542.     (void) NoSignExtend(dvifp, 4);   /* width of widest page */
  3543.     if (NoSignExtend(dvifp, 2) >= STACK_SIZE)
  3544.         Fatal ("Stack size is too small");
  3545.     (void) NoSignExtend(dvifp, 2);   /* this reads the number of pages in */
  3546.                      /* the DVI file */
  3547. #ifdef DEBUG
  3548.     if (Debug)
  3549.         fprintf(stderr,"now reading font defs");
  3550. #endif
  3551.     if (load)
  3552.         GetFontDef ();
  3553. }
  3554.  
  3555.  
  3556. /*-->LoadAChar*/
  3557. /**********************************************************************/
  3558. /***************************** LoadAChar ******************************/
  3559. /**********************************************************************/
  3560. void
  3561. LoadAChar(c, ptr)
  3562. long4    c;
  3563. register struct char_entry *ptr;
  3564. {
  3565.     long4    *pr;
  3566.     long4    bytes;
  3567.  
  3568.     if (ptr->where.address.fileOffset == NONEXISTANT 
  3569. #ifdef LJ_RESIDENT_FONTS
  3570.     || fontptr->resident_p
  3571. #endif
  3572.     ) {
  3573.       ptr->where.isloaded = _FALSE;
  3574.       return;
  3575.     }
  3576.  
  3577.     OpenFontFile();
  3578.  
  3579. #ifdef DEBUG
  3580.     if (Debug)
  3581.       fprintf(stderr, "LoadAChar: <%c>(%ld) from file at pos %ld\n",
  3582.           (char)c,(long)c,(long)ptr->where.address.fileOffset);
  3583. #endif
  3584.  
  3585. #ifdef USEPXL
  3586.  
  3587.     fseek(pxlfp, ptr->where.address.fileOffset, 0);
  3588.  
  3589.     if (fontptr->id == pk89) {
  3590. #ifdef PARANOIA
  3591.         unsigned char   temp;
  3592.         temp = (unsigned char) NoSignExtend(pxlfp, 1);
  3593.  
  3594.         if ((int)(ptr->flag_byte) != (int)temp) {
  3595.            fprintf(stderr,"font=%lx, ptr=%lx\n",fontptr,ptr);
  3596.                 Fatal("%d: oh boy! old flag %d, new flag %d, ptr=%lx\n",
  3597.                           (int)c,(int)(ptr->flag_byte),(int)temp,ptr);
  3598.             }
  3599. #endif
  3600.  
  3601.         if ((ptr->flag_byte & 7) == 7) {
  3602.             bytes = ((long4) NoSignExtend(pxlfp, 4)) - 28;
  3603.             fseek(pxlfp, ptr->where.address.fileOffset + 36, 0);
  3604. /*
  3605. fprintf(stderr,"bytes=%ld, seeking at %ld\n",
  3606.             (long)bytes, (long)ptr->where.address.fileOffset + 36);
  3607. */
  3608.         } else if ((ptr->flag_byte & 4) == 4) {
  3609.             bytes = ((long4)ptr->flag_byte & 3)
  3610.                 * 65536l + NoSignExtend(pxlfp, 2) - 13;
  3611.             fseek(pxlfp, ptr->where.address.fileOffset + 16, 0);
  3612.         } else {
  3613.             bytes = ((long4)ptr->flag_byte & 3)
  3614.                 * 256 + NoSignExtend(pxlfp, 1) - 8;
  3615.             fseek(pxlfp, ptr->where.address.fileOffset + 10, 0);
  3616.         }
  3617.     } else if (fontptr->id == id1002)
  3618.         bytes =  ((( (long4)ptr->width + 7) >> 3) * (long4) ptr->height);
  3619.     else if (fontptr->id == id1001)
  3620.         bytes =  4 * (((long4)ptr->width + 31) >> 5) * (long4)ptr->height;
  3621.     else 
  3622.         bytes = 0;
  3623.  
  3624.     if (bytes > 0) {
  3625.                                           /* do NOT load Huge characters */
  3626.       if ((bytes > HUGE_CHAR_PATTERN) && (fontptr->id != pk89)) {
  3627.     qfprintf(stderr,"Huge Character <%c> (%ld Bytes)\n", (char)c, (long)bytes);
  3628.         ptr->charsize = HUGE_SIZE;
  3629.         ptr->where.isloaded = _FALSE;
  3630.       } else {
  3631.         if ( (pr = (long4 *)malloc( bytes )) == NULL )
  3632.             Fatal("Unable to allocate %ld bytes for char <%c>\n",
  3633.                          (long)bytes, (char)c);
  3634. /*
  3635.  * else fprintf(stderr,"allocating %ld bytes char <%c>(%d)\t at 0x%lx\n",
  3636.  *                       (long)bytes, (char)c,(int)c,(long)pr);
  3637.  */ 
  3638. #ifdef DEBUG
  3639.         if (Debug)
  3640.           fprintf(stderr,
  3641.            "Allocating Char <%c>, FileOffset=%lX, Bytes=%ld (%d) <%d>\n",
  3642.               (char) c, (long)ptr->where.address.fileOffset, (long)bytes,
  3643.               (int)bytes, (unsigned int)bytes);
  3644. #endif
  3645.         allocated_storage += bytes;
  3646.         fread(pr, 1, (int) bytes , pxlfp);
  3647.         ptr->where.address.pixptr = pr;
  3648.       }
  3649.     } 
  3650. #else
  3651.     fseek(gfin, ptr->where.address.fileOffset, 0);
  3652.     gettochar();
  3653.     readbits();
  3654.     if (num_bytes > HUGE_CHAR_PATTERN)
  3655.       ptr->charsize = HUGE_SIZE;
  3656. #endif
  3657.     ptr->where.isloaded = _TRUE; 
  3658.     if (ptr->charsize != SMALL_SIZE
  3659. #ifdef LJ
  3660.         /* we might have problems at the edge of the paper with diff. sized characters
  3661.          * the correct treatment would be to check whether the bounding box of 
  3662.          * tfontptr is within the paper relative to the current position  
  3663.          */
  3664.     || fontptr->max_height > CHAR_HEIGTH_LARGE  
  3665.     || (rasterfont[fontptr->plusid])
  3666. #endif
  3667.        )
  3668.         return;
  3669.  
  3670.     EmitChar(c, ptr);
  3671. #ifdef USEPXL
  3672.     /* we should really free the space used by the PXL data after this
  3673.        point, but it is not large, and besides, we may want to be
  3674.        more clever in the future, about sending bitmaps.  So keep
  3675.        the data around */
  3676. #endif
  3677. }
  3678. /*-->SetChar*/
  3679. /**********************************************************************/
  3680. /*****************************  SetChar  ******************************/
  3681. /**********************************************************************/
  3682. void
  3683. SetChar(c, command, PassNo, do_posn,in_string)
  3684. long4    c;
  3685. short   command;
  3686. int     PassNo;
  3687. bool do_posn,in_string;
  3688. {
  3689.     register struct char_entry *ptr;  /* temporary char_entry pointer */
  3690.     bool pos_after = _FALSE;
  3691.  
  3692.     ptr = &(fontptr->ch[c]);
  3693.     if (!((ptr->where.isloaded) || (ptr->charsize == HUGE_SIZE)))
  3694.         LoadAChar(c, ptr);
  3695.     if (PassNo == 0)
  3696.         return;
  3697.  
  3698.     if (do_posn) {
  3699. #ifdef IBM3812
  3700.         if (CharStringPos>0) {
  3701.             fprintf(stderr,"!!!! That should never happen!!!\n");
  3702.             CharStringOut;
  3703.         }
  3704. #endif
  3705.         SetPosn(h, v);
  3706.     }
  3707.  
  3708. /*
  3709. printf("(%d) hh=%ld (+%ld/+%ld), h=%ld, xh=%ld,xhh=%ld, [%ld|%ld] ->%d\n",
  3710.     (int)do_posn,(long)hh,(long)ptr->cw,(long)ptr->cw*(long)hconv,(long)h,
  3711.     (long)PIXROUND(h, hconv),
  3712.     (long)PIXROUND(hh, hconv),
  3713.     (long)labs((hh-h)),(long)hconv,(labs((hh-h))>hconv)
  3714.     );
  3715. */
  3716.  
  3717.     if (in_string && (labs((hh-h))>hconv)) {
  3718. #ifdef IBM3812
  3719.         CharStringOut;
  3720. #endif
  3721.         SetPosn(h, v);
  3722.     }
  3723.  
  3724. /*
  3725. fprintf(stderr,"raster?=%d - last_ry=%d, last_rx=%d,mmax-height=%d\n",
  3726.     (int)last_ry < fontptr->max_height, (int)last_ry,(int)last_rx,
  3727.     (int)fontptr->max_height);
  3728. */
  3729.  
  3730.     if (fontptr->font_file_id != NO_FILE) {      /* ignore missing fonts */
  3731.          if (
  3732. #ifdef LJ_RESIDENT_FONTS
  3733.          !fontptr->resident_p && 
  3734. #endif
  3735.          (ptr->charsize != SMALL_SIZE 
  3736. #ifdef LJ
  3737.           /* the LaserJet cannot print characters 
  3738.            * where the bounding box lies outside the 
  3739.            * paper edge. Missing: right paper edge
  3740.            */
  3741.           || last_ry < (int)fontptr->max_height
  3742.           || fontptr->max_height > CHAR_HEIGTH_LARGE
  3743.           || (rasterfont[fontptr->plusid])
  3744. /***** KYOCERA *****/
  3745. #ifdef SEVENBIT
  3746.               || (c==32)
  3747. #endif
  3748. /***** KYOCERA *****/
  3749. #endif
  3750.           )) {
  3751. #ifdef LJ
  3752.       int     tmp;
  3753.       char    sign;
  3754.       
  3755.       if (!do_posn) {
  3756.         SetPosn(h, v);
  3757.       }
  3758. #ifdef USEPXL
  3759.       tmp = (int) -ptr->yOffset;
  3760. #else
  3761.       tmp = (int) num_rows-y_offset;
  3762. #endif
  3763.       if (tmp != 0) {
  3764.         if (tmp < 0) {
  3765.           sign = '-'; tmp = -tmp;
  3766.         } else
  3767.           sign = '+';
  3768.         EMIT(outfp, "\033*p%c%dY", sign, tmp);
  3769.       }
  3770. #ifdef USEPXL
  3771.       tmp = (int) -ptr->xOffset;
  3772. #else
  3773.       tmp = (int) -x_offset;
  3774. #endif
  3775.       if (tmp != 0) {
  3776.         if (tmp < 0) {
  3777.           sign = '-'; tmp = -tmp;
  3778.         } else
  3779.           sign = '+';
  3780.         EMIT(outfp, "\033*p%c%dX", sign, tmp);
  3781.       }
  3782. #endif
  3783. #ifdef IBM3812
  3784.       CharStringOut;
  3785. #endif
  3786. #ifdef DEBUG
  3787.     if (Debug)
  3788. #ifndef vms
  3789.         fprintf(stderr,"Raster character <%c> %hd\n", (char) c,(short)c);
  3790. #else
  3791.         fprintf(stderr,"Raster character <%c> %d\n", (char) c,(short)c);
  3792. #endif
  3793. #endif
  3794.             RasterChar(ptr);
  3795.             pos_after = _TRUE;
  3796.         } else {
  3797.         unsigned char cc;
  3798.         cc = VisChar((char)c);
  3799. #ifdef IBM3812
  3800. #ifdef USEPXL
  3801.             if ( ptr->yyOffset || (!in_string) ) {
  3802.                 CharStringOut;
  3803.                 MoveVert(ptr->yyOffset);
  3804.                 sprintf(PMPformat, "\01%c", cc);
  3805.                 PMPout(2, PMPformat);
  3806.                 MoveVert((int)-(ptr->yyOffset));
  3807.             } else {
  3808. #endif
  3809.                 if (CharStringPos==CHARSTRINGMAX)
  3810.                     CharStringOut;
  3811.  
  3812.                 CharString[CharStringPos] = cc;
  3813.                 CharStringPos++;
  3814. #ifdef USEPXL
  3815.         }
  3816. #endif
  3817. #endif
  3818. #ifdef LJ
  3819. #define TRANSPARENTCHAR(ch) \
  3820.         if ((ch == 0l) || (ch >= 7l && ch <= 15l) || (ch == 27l)) \
  3821.         EMIT(outfp, "\033&p1X%c", (unsigned char)ch); \
  3822.         else EMITC((unsigned char)ch)
  3823. #ifdef USEPXL
  3824.             if (ptr->yyOffset) {
  3825. #ifndef vms
  3826.                 EMIT(outfp, "\033*p+%hdY", ptr->yyOffset);
  3827.                 TRANSPARENTCHAR(cc);
  3828.                 EMIT(outfp, "\033*p-%hdY", ptr->yyOffset);     /* GUGUGU 255 */
  3829. #else
  3830.                 EMIT(outfp, "\033*p+%dY", ptr->yyOffset);
  3831.                 TRANSPARENTCHAR(cc);
  3832.                 EMIT(outfp, "\033*p-%dY", ptr->yyOffset);     /* GUGUGU 255 */
  3833. #endif
  3834.             } else
  3835. #endif
  3836. /*                EMITC( (unsigned char)c);*/
  3837.                { TRANSPARENTCHAR(cc);}
  3838. #endif
  3839.       }
  3840.         hh += (long4) ptr->cw*hconv;
  3841.     }
  3842.     if (command <= SET4)
  3843.         h += ptr->tfmw;
  3844.     if (pos_after) {
  3845.         SetPosn(h, v);
  3846.       }
  3847. }
  3848.  
  3849.  
  3850. void
  3851. DoBop()
  3852. {
  3853.     struct font_entry *p;
  3854. #ifdef LJ
  3855.     register short i;
  3856.     if (fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
  3857.        for (i = 0; i < HANDLE_MAX_FONTS; i++)
  3858.           rasterfont[i] = _FALSE;
  3859.     }
  3860.     fonts_used_on_this_page = 0;
  3861. #endif
  3862.     for (p = hfontptr; p; p = p->next) {
  3863.         p->used_on_this_page = _FALSE;
  3864.     }
  3865. }
  3866.  
  3867.  
  3868. /*-->SetFntNum*/
  3869. /**********************************************************************/
  3870. /****************************  SetFntNum  *****************************/
  3871. /**********************************************************************/
  3872. void
  3873. SetFntNum(k, Emitting)
  3874. long4    k;
  3875. bool Emitting;
  3876. /*  this routine is used to specify the font to be used in printing future
  3877.     characters */
  3878. {
  3879. #ifdef LJ
  3880.     static unsigned short plusid = 0;
  3881. #endif
  3882.     fontptr = hfontptr;
  3883.     while ((fontptr != NULL) && (fontptr->k != k))
  3884.         fontptr = fontptr->next;
  3885.     if (fontptr == NULL)
  3886.         Fatal("font %ld undefined", (long)k);
  3887.     if (Emitting && fontptr->font_file_id != NO_FILE) {
  3888.         if (!fontptr->used_on_this_page
  3889. #ifdef LJ_RESIDENT_FONTS
  3890.         && !fontptr->resident_p
  3891. #endif
  3892.         ) {
  3893.             fontptr->used_on_this_page = _TRUE;
  3894. #ifdef LJ
  3895.             if (++fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
  3896.               qfprintf(stderr,"this is the %d. font on this page!",
  3897.                        fonts_used_on_this_page);
  3898.               qfprintf(stderr," (max = %d) rastering characters!\n",
  3899.                        MAX_FONTS_PER_PAGE);
  3900.                rasterfont[fontptr->plusid] = _TRUE;
  3901.             }
  3902. #endif
  3903.         }
  3904. #ifdef DEBUG
  3905.     if (Debug)
  3906.       fprintf(stderr, "Switching to font #%ld (%s).\n", k, fontptr->n);
  3907. #endif
  3908.         /* activate font */
  3909. #ifdef IBM3812
  3910.         sprintf(PMPformat, "\323%c", (unsigned char)fontptr->plusid);
  3911.         PMPout(2, PMPformat);
  3912. #endif
  3913. #ifdef LJ
  3914.         if (!rasterfont[fontptr->plusid]) {
  3915. #ifdef LJ_RESIDENT_FONTS
  3916.       if (fontptr->resident_p) {
  3917. #ifdef DEBUG
  3918.             if (Debug)
  3919.               fprintf(stderr, "Resident font #%d.\n", fontptr->resid);
  3920. #endif
  3921.         EMIT(outfp, "\033(%s", fontptr->symbol_set);
  3922.         EMIT(outfp, "\033(s%up%.2f%c%us%db%uT",
  3923.                 fontptr->spacing,
  3924.                 /* height in points, or pitch */
  3925.                 fontptr->spacing ? fontptr->s / 65536.0
  3926.                                          : fontptr->pitch ,
  3927.                         fontptr->spacing ? 'v' : 'h', /* height or pitch? */
  3928.                         fontptr->style,       /* upright, italic, ... */
  3929.                         fontptr->weight,      /* regular, bold, ... */
  3930.                         fontptr->resid);
  3931.       } else
  3932. #endif /* LJ_RESIDENT_FONTS */      
  3933.           if (fontptr->plusid>0) EMIT(outfp, "\033(%dX", fontptr->plusid);
  3934.           else                   EMIT(outfp, "\033(X");
  3935.         }
  3936. /* else fprintf(stderr,"I am doing rasterfont for plusid=%d instead\n",
  3937.                 fontptr->plusid);
  3938. */
  3939. #endif
  3940.     }
  3941. #ifdef LJ    /* reassignment of printer font id  0.48 */
  3942.     else if (fontptr->font_file_id != NO_FILE
  3943. #ifdef LJ_RESIDENT_FONTS
  3944.          && !fontptr->resident_p
  3945. #endif    
  3946.          ) {
  3947.       if (fontptr->ncdl == 0) {
  3948. #ifdef DEBUG
  3949.     if (Debug)
  3950.       fprintf(stderr, "Changing plusid from %d to %d\n", 
  3951.           fontptr->plusid, (int)plusid);
  3952. #endif
  3953.     fontptr -> plusid = plusid;
  3954.     plusid ++;
  3955.       }
  3956.     }
  3957. #endif
  3958. }
  3959.  
  3960.  
  3961. /*-->SetPosn*/
  3962. /**********************************************************************/
  3963. /*****************************  SetPosn  ******************************/
  3964. /**********************************************************************/
  3965. void                  /* output a positioning command */
  3966. SetPosn(x, y)
  3967. long4    x, y;
  3968. {
  3969.     int     rx, ry;
  3970.     rx = (int)PIXROUND(x, hconv) + x_goffset;
  3971.     ry = (int)PIXROUND(y, vconv) + y_goffset;
  3972.  
  3973. /*
  3974. * fprintf(stderr,"setposn to %ld/%ld, %d/%d\n",(long)x,(long)y,rx,ry);
  3975. */
  3976.  
  3977. #ifdef IBM3812
  3978.     PMPcont(3);
  3979.     PMPoutC('\340');
  3980.     EMITWORD(LARGER(rx,0));
  3981.  
  3982.     if (last_ry != ry) { /* necessary to set new y-position */
  3983.         PMPcont(3);
  3984.         PMPoutC('\341');
  3985.         EMITWORD(LARGER(ry,0));
  3986.     }
  3987. #endif
  3988. #ifdef LJ
  3989.     if (last_ry != ry)   /* necessary to set new y-position */
  3990.         EMIT(outfp, "\033*p%dx%dY", LARGER(rx,0), LARGER(ry,0));
  3991.     else
  3992.         EMIT(outfp, "\033*p%dX", LARGER(rx,0));
  3993. #endif
  3994.  
  3995.     last_ry = ry;    /* last y-position on output device */
  3996.     last_rx = rx;    /* last x-position on output device */
  3997. /*
  3998.  * must know where device "really" is horizontally, for rel. posning.
  3999.  * (maybe in the future), but we always use direct positioning for
  4000.  * vertical movement.
  4001.  */
  4002.     /* hh = rx * hconv; */
  4003.     hh = x;
  4004.     vv = y;
  4005. /*
  4006.  *     fprintf(stderr,"DoPosn: x=%ld, y=%ld, rx=%d, ry=%d, hh=%ld, vv=%ld\n",
  4007.  *               (long)x,(long)y,rx,ry,(long)hh,(long)vv);
  4008.  */
  4009. }
  4010.  
  4011.  
  4012. #ifdef IBM3812
  4013. /*-->PMPLine*/
  4014. /**********************************************************************/
  4015. /*****************************  PMPLine  ******************************/
  4016. /**********************************************************************/
  4017. void       /* drawing lines on the 3812 using PMP vector commands */
  4018. PMPLine(w, y, x)
  4019. int     w, y, x;
  4020. {
  4021.  
  4022.     if ((w == 0) || ((x == 0) && (y == 0)))
  4023.         return;
  4024.  
  4025. /*
  4026. fprintf(stderr,"w=%d / %d - %d, y=%d / %d - %d, x=%d / %d - %d\n",
  4027.         w,(char)(w & 0xff),(int)((signed_char)(w & 0xff)),
  4028.         y,(char)(y & 0xff),(int)((signed_char)(y & 0xff)),
  4029.         x,(char)(x & 0xff),(int)((signed_char)(x & 0xff)));
  4030. */
  4031.  
  4032.     if ( (((signed_char)(x & 0xff)) == x ) &&
  4033.         ( ((signed_char)(y & 0xff)) == y ) ) {
  4034.         PMPcont(6);
  4035.         PMPout(1, "\370");
  4036.         EMITWORD(3);      /* length of vector */
  4037.         PMPoutC((unsigned char)(0x80 | 0x00 | (unsigned char) w));
  4038.         PMPoutC((signed_char)(y & 0xff));
  4039.         PMPoutC((signed_char)(x & 0xff));
  4040. /*
  4041.         fprintf(stderr,"F8 00 03: w=%d, x=%d(%d-%.2X), y=%d(%d-%.2X),\n",
  4042.         w,x,(char)(x & 0xff),(signed_char)(x & 0xff),
  4043.           y,(char)(y & 0xff),(signed_char)(y & 0xff));
  4044. */
  4045.  
  4046.     } else {
  4047.         PMPcont(8);
  4048.         PMPout(1, "\370");
  4049.         EMITWORD(4 + 1);      /* length of vector */
  4050.         PMPoutC((unsigned char)(0xC0 | 0x00 | (unsigned char) w));
  4051.         EMITWORD(y);
  4052.         EMITWORD(x);
  4053. /*
  4054.         fprintf(stderr,"F8 00 05: w=%d, x=%d, y=%d,\n", w,x,y);
  4055. */
  4056.     }
  4057. }
  4058.  
  4059.  
  4060. #endif
  4061. /*-->SetRule*/
  4062. /**********************************************************************/
  4063. /*****************************  SetRule  ******************************/
  4064. /**********************************************************************/
  4065. void                   /*   this routine will draw a rule */
  4066. SetRule(a, b, Set)
  4067. long4    a, b;
  4068. int     Set;
  4069. {
  4070.     long4    xx, yy;
  4071. #ifdef IBM3812
  4072.     short   hor_offset, vert_offset, ll;
  4073. #endif
  4074.     if ( a > 0 && b > 0 ) {
  4075.         SetPosn(h, v);             /* lower left corner */
  4076.         xx = (long4)PIXROUND(b, hconv);     /* width */
  4077.         yy = (long4)PIXROUND(a, vconv);     /* height */
  4078.  
  4079. #ifdef DEBUG
  4080.         if (Debug)
  4081.             fprintf(stderr,"Rule xx=%ld, yy=%ld\n", (long)xx, (long)yy);
  4082. #endif
  4083.  
  4084. #ifdef IBM3812
  4085.         hor_offset  = (short)(last_ry - yy);
  4086.         if (hor_offset < 0) yy += hor_offset;
  4087.         if (last_rx < 0) xx += last_rx;
  4088.  
  4089.         if (Landscape) {
  4090.           if (last_ry > MAX_PAGE_WIDTH) yy += MAX_PAGE_WIDTH-last_ry;
  4091.           hor_offset  = (short)(MAX_PAGE_HEIGHT - (last_rx + xx));
  4092.         } else {
  4093.           if (last_ry > MAX_PAGE_HEIGHT) yy += MAX_PAGE_HEIGHT-last_ry;
  4094.           hor_offset  = (short)(MAX_PAGE_WIDTH - (last_rx + xx));
  4095.         }
  4096.         if (hor_offset < 0) xx += hor_offset;
  4097.  
  4098.         if ((xx > 31) && (yy > 31)) {
  4099. /*
  4100.  *   fill area by multiple lines  (kind of a mess)
  4101.  *   process for simplicity always horizontally
  4102.  */
  4103.  
  4104. /* fprintf(stderr, "large box: w=%d, x=%d, y=%d\n",(int)yy,(int)xx,0);*/
  4105.  
  4106.             hor_offset  = HOR_HALF(30);
  4107.             MoveHor(hor_offset);
  4108.             vert_offset = VERT_HALF(30);
  4109.             MoveVert(-vert_offset);
  4110.             ll = (short)xx - 30;
  4111.  
  4112.             for (; yy > 30; yy -= 30) {
  4113.                 PMPLine(30, 0, ll);
  4114.                 MoveHor(-ll);
  4115.                 MoveVert(-30);
  4116.             }
  4117.  
  4118.             hor_offset  = -hor_offset     + HOR_HALF(yy);
  4119.             MoveHor(hor_offset);
  4120.             vert_offset = (vert_offset - 30) + VERT_HALF(yy);
  4121.             MoveVert(-vert_offset);
  4122.  
  4123.             PMPLine((int)yy, 0, (int)(xx - yy));
  4124.  
  4125.         } else if ( (yy < xx) && (xx > 0) ) {
  4126.  
  4127. /* fprintf(stderr, "hori rule: w=%d, x=%d, y=%d\n",(int)yy,(int)(xx-yy),0);*/
  4128.  
  4129.             hor_offset  = HOR_HALF(yy);
  4130.             vert_offset = VERT_HALF(yy);
  4131.  
  4132.             MoveHor(hor_offset);
  4133.             MoveVert(-vert_offset);
  4134.  
  4135.             PMPLine((int)yy, 0, (int)(xx - yy));
  4136.         } else if ( (xx < yy) && (yy > 0)) {
  4137.  
  4138.             hor_offset  = HOR_HALF(xx);
  4139.             vert_offset = VERT_HALF(xx);
  4140. /*
  4141.  fprintf(stderr, "move: x=%d, y=%d\n",hor_offset,-vert_offset);
  4142.  fprintf(stderr, "vert rule: w=%d, x=%d, y=%d\n",(int)xx,0,(int)-(yy-xx));
  4143. */
  4144.             MoveHor(hor_offset);
  4145.             MoveVert(-vert_offset);
  4146.  
  4147.             PMPLine((int)xx, (int)-(yy - xx), 0);
  4148.         } else if (xx == yy) {
  4149.             short     y0;  /* small square box!! */
  4150.  
  4151.             y0 = (short)yy / 2;
  4152.             hor_offset  = HOR_HALF(y0);
  4153.             MoveHor(hor_offset);
  4154.             vert_offset = VERT_HALF(y0);
  4155.             MoveVert(-vert_offset);
  4156.             ll = (short)xx - y0;
  4157.  
  4158.             PMPLine((int)y0, 0, ll);
  4159.  
  4160.             hor_offset  = -(ll + hor_offset);
  4161.             vert_offset = (y0 - vert_offset);
  4162.  
  4163.             yy -= (long4)y0;
  4164.             hor_offset  += HOR_HALF(yy);
  4165.             MoveHor(hor_offset);
  4166.             vert_offset += VERT_HALF(yy);
  4167.             MoveVert(-vert_offset);
  4168.  
  4169.             PMPLine((int)yy, 0, (int)xx - yy);
  4170.         }
  4171. #endif
  4172. #ifdef LJ
  4173.     if (last_ry + 1 < yy) yy = last_ry + 1;
  4174.     if (last_rx < 0) xx += last_rx;
  4175.  
  4176.     if (((int)pgsiz_dots >0) && ((int)last_ry > (int)pgsiz_dots))
  4177.       yy += (long4)pgsiz_dots - (long4)last_ry;
  4178.  
  4179.         if ((yy>0) && (xx>0))
  4180.                 EMIT(outfp, "\033*p-%ldY\033*c%lda%ldbP", (long)yy - 1, (long)xx, (long)yy);
  4181. #endif
  4182.         last_ry = UNKNOWN;       /* next time full positioning */
  4183.     }
  4184.     if (Set)
  4185.         h += b;
  4186. }
  4187.  
  4188.  
  4189. /*-->SetString*/
  4190. /**********************************************************************/
  4191. /*****************************  SetString  ****************************/
  4192. /**********************************************************************/
  4193. void
  4194. SetString(firstch, PassNo)    /* read and set a consecutive string of chars */
  4195. short   firstch;
  4196. int     PassNo;
  4197. {
  4198.     short   c;
  4199.     register unsigned short i;
  4200.  
  4201. #ifdef DEBUG
  4202.     if (Debug)
  4203.       fprintf(stderr, "SetString ");
  4204. #endif
  4205.     for (i = 0, c = firstch; c >= SETC_000 && c <= SETC_127; i++) {
  4206. #ifdef DEBUG
  4207.         if (Debug)
  4208.           fprintf(stderr, "%d(%c) ", c, c);
  4209. #endif
  4210.         SetChar((long4)c,  c, PassNo, (bool)(i==0),_TRUE);
  4211.         c = (short) NoSignExtend(dvifp, 1);
  4212.     }
  4213.     fseek(dvifp, -1l, 1);    /* backup one character */
  4214. #ifdef IBM3812
  4215.     CharStringOut;
  4216. #endif
  4217. #ifdef DEBUG
  4218.     if (Debug)
  4219.       fprintf(stderr, "...SetString\n");
  4220. #endif
  4221. }
  4222.  
  4223. #ifndef ARITHMETIC_RIGHT_SHIFT
  4224. long4   signTab[5] = {0,0x00000080,0x00008000,0x00800000,0x00000000};
  4225. long4 extendTab[5] = {0,~0^0xff,~0^0xffff,~0^0xffffff,~0^0xffffffff};
  4226. #endif
  4227.  
  4228. /*-->SignExtend*/
  4229. /**********************************************************************/
  4230. /****************************  SignExtend  ****************************/
  4231. /**********************************************************************/
  4232. long4
  4233. SignExtend(fp, n)   /* return n byte quantity from file fd */
  4234. register FILE *fp;  /* file pointer    */
  4235. register int    n;  /* number of bytes */
  4236. {
  4237.     int     n1;     /* number of bytes      */
  4238.     long4    x;      /* number being constructed */
  4239. #ifdef SIGN_DEBUG
  4240.     long4    x0;     /* copy of x  */
  4241. #endif
  4242.     x = getc(fp);   /* get first (high-order) byte */
  4243.     n1 = n--;
  4244.     while (n--)  {
  4245.         x <<= 8;
  4246.         x |= getc(fp);
  4247.     }
  4248. /*
  4249.  *   NOTE: This code assumes that the right-shift is an arithmetic, rather
  4250.  *   than logical, shift which will propagate the sign bit right.   According
  4251.  *   to Kernighan and Ritchie, this is compiler dependent!
  4252.  */
  4253.  
  4254. #ifdef SIGN_DEBUG
  4255.     x0 = x;
  4256. #endif
  4257.  
  4258. #ifdef ARITHMETIC_RIGHT_SHIFT
  4259.     x <<= 32 - 8 * n1;
  4260.     x >>= 32 - 8 * n1; /* sign extend */
  4261. #else
  4262.     if (x & signTab[n1]) x |= extendTab[n1];
  4263. #endif
  4264.  
  4265. #ifdef SIGN_DEBUG
  4266.     fprintf(stderr,"\tSignExtend(fp,%d)=%lX, was=%lX,%d\n",
  4267.         n1,x,x0,x0&signTab[n1]);
  4268. #endif
  4269.  
  4270. #ifdef DEBUG
  4271.     if (Debug > 1)
  4272.         fprintf(stderr,"\tSignExtend(fp,%d)=%lx\n", n1, x);
  4273. #endif
  4274.     return(x);
  4275. }
  4276.  
  4277.  
  4278. /*-->SkipFontDef*/
  4279. /**********************************************************************/
  4280. /****************************  SkipFontDef  ***************************/
  4281. /**********************************************************************/
  4282. void
  4283. SkipFontDef()
  4284. {
  4285.     int     a, l;
  4286.     char    n[STRSIZE];
  4287.  
  4288.     (void) NoSignExtend(dvifp, 4);
  4289.     (void) NoSignExtend(dvifp, 4);
  4290.     (void) NoSignExtend(dvifp, 4);
  4291.     a = (int) NoSignExtend(dvifp, 1);
  4292.     l = (int) NoSignExtend(dvifp, 1);
  4293.     GetBytes(dvifp, n, a + l);
  4294. }
  4295.  
  4296.  
  4297. /*-->Warning*/
  4298. /**********************************************************************/
  4299. /*****************************  Warning  ******************************/
  4300. /**********************************************************************/
  4301. void                           /* issue a warning */
  4302. Warning(fmt, a, b, c, d)
  4303. char    *fmt;         /* format    */
  4304. char    *a, *b, *c, *d;   /* arguments */
  4305. {
  4306.     if ( G_nowarn || G_quiet )
  4307.         return;
  4308.  
  4309.     fprintf(stderr, "%s: warning: ", G_progname);
  4310.     fprintf(stderr, fmt, a, b, c, d);
  4311.     fprintf(stderr, "\n");
  4312. }
  4313.  
  4314. void
  4315. PutWord(w)
  4316. int     w;
  4317. {
  4318.     EMITC((char)(w >> 8) & 0xff);
  4319.     EMITC((char)w & 0xff);
  4320. }
  4321.  
  4322.  
  4323. #ifdef IBM3812
  4324. /*-->PMPout*/
  4325. /*****************************************************************************/
  4326. /* This routine produces the PMP-envelopes for the 3812. Its semantics are:
  4327.  
  4328.    first arg == 0  ... flush buffer
  4329.    first arg == -1 ... number of bytes specified in the second argument
  4330.                have to be continuous, that is they must not
  4331.                be disrupted by ENTER PMP etc.
  4332.    first arg > 0       output first arg bytes
  4333.  
  4334.                If arg2 > OUTBUFSIZE ... flush buffer,
  4335.                         switch to unbuffered mode
  4336.                         (dont't collect PMP commands)
  4337.                If arg2+bufferpointer > OUTBUFSIZE ... flush buffer,
  4338.                         block will fit into buffer
  4339.                otherwise ..... block will fit into buffer
  4340.  
  4341.   Buffering is done to reduce the ENTER PMP-commands. Initially
  4342.   the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is
  4343.   necessary to enter PMP mode. The ENTER-PMP-command contains the
  4344.   number of bytes that will be interpreted as PMP-commands. In the
  4345.   most naive approach for each primitive command (eg. set cursor) you
  4346.   have to produce a seperate ENTER-PMP-envelope (5 bytes). It is
  4347.   favourable to collect as many PMP commands as possible in one envelope. */
  4348. /*****************************************************************************/
  4349. void
  4350. PMPout(l, s)
  4351. char    *s;
  4352. int     l;
  4353. {
  4354.     static char     buffer[OUTBUFSIZE];
  4355.     static unsigned short   bp = 0;         /* range 0..OUTBUFSIZE */
  4356.     static long4     continuous = 0l;
  4357.     static bool buffered = _TRUE;
  4358.  
  4359.     if (l == 0) {
  4360.         if (bp == 0)
  4361.             return;
  4362.         EMIT(outfp, "\033[C%c%c", (unsigned char)(bp & 0xFF),
  4363.             (unsigned char)(bp >> 8));
  4364.         EMITB((int)bp, buffer);
  4365.         bp = 0;
  4366.         return;
  4367.     }
  4368.     if (l == -1) {
  4369.         continuous = (long4)s;
  4370.         if (continuous + (long4)bp + 5l > (long4) OUTBUFSIZE)
  4371.             PMPflush;
  4372.         buffered = (bool) ((continuous + 5l <= (long4) OUTBUFSIZE));
  4373.         if (!buffered) {
  4374.             EMIT(outfp, "\033[C%c%c",
  4375.                 (unsigned char)(continuous & 0xFF),
  4376.                 (unsigned char)((continuous >> 8) & 0xFF));
  4377.         }
  4378.         return;
  4379.     }
  4380.     if (buffered) {
  4381.         register int    i;
  4382.         if ( ((long4)l + bp) > OUTBUFSIZE)
  4383.             PMPflush;
  4384.         for (i = 0; i < l; i++)
  4385.             buffer[bp+i] = s[i];
  4386.         bp += (unsigned short)l;
  4387.     } else {
  4388.         EMITB((int)l, s);
  4389.         buffered = (bool) ((continuous -= (long4)l) <= 0) ;
  4390.     }
  4391. }
  4392.  
  4393.  
  4394. void
  4395. PMPoutC(c)
  4396. char    (c);
  4397. {
  4398.     PMPout(1, &c);
  4399. }
  4400.  
  4401.  
  4402. #endif
  4403. #ifdef MSDOS
  4404. /*-->AssureBinary*/
  4405. /**********************************************************************/
  4406. /*************************** AssureBinary *****************************/
  4407. /**********************************************************************/
  4408. /* This procedure is both DOS AND MSC dependent. The MSC file open on */
  4409. /* a device ignores the 'binary' of the "wb" parameter and opens the  */
  4410. /* file in ascii mode. This procedure sets the file f to binary mode  */
  4411. /* if it is connected to a device that is not console input or output */
  4412. /* or the null device. For other operating systems this routine is    */
  4413. /* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */
  4414. /**********************************************************************/
  4415. void
  4416. AssureBinary(f)
  4417. FILE *f;
  4418. {
  4419.     union REGS regs;              /* registers for bios call */
  4420.  
  4421.     regs.h.ah = (unsigned char) 0x44;     /* IOCTL            */
  4422.     regs.h.al = (unsigned char) 0x00;     /* get device information   */
  4423.     regs.x.bx = (unsigned int) fileno(f); /* handle from MSC      */
  4424.     intdos(®s, ®s);         /* call DOS interrupt       */
  4425.                           /* ---> result in DX    */
  4426.  
  4427.     if (  (regs.h.dl & 0x80)     /* file handle points to a device */
  4428.          && !(regs.h.dl & 0x07) )    /* neither console i/o or null    */ {
  4429.  
  4430.         regs.h.dl  |= 0x20;      /* set BINARY bit in device info  */
  4431.  
  4432.         regs.h.ah = (unsigned char) 0x44;    /* IOCTL         */
  4433.         regs.h.al = (unsigned char) 0x01;    /* set device information*/
  4434.         regs.x.bx = (unsigned int) fileno(f); /* handle from MSC      */
  4435.         regs.h.dh = (unsigned char) 0x00;    /* clear DH          */
  4436.         intdos(®s, ®s);           /* call DOS interrupt     */
  4437.     }
  4438. }
  4439.  
  4440.  
  4441. #endif
  4442.  
  4443. #ifdef USEPXL
  4444. bool getbit ();
  4445. unsigned char   getnyb ();
  4446. long4    pk_packed_num ();
  4447.  
  4448.  
  4449. #define  PKBYTE   *pkloc; pkloc ++
  4450. #define  OUTCHAR(c) raster_line_buf[bp]= (unsigned char)c; bp++
  4451.  
  4452. unsigned char   bitweight, inputbyte ;
  4453. unsigned char   dyn_f ;
  4454. unsigned char   *pkloc;
  4455. int     repeatcount;
  4456.  
  4457. void              /* <Read and translate raster description@>*/
  4458. PkRaster(ce, raster)
  4459. struct char_entry *ce;
  4460. bool raster;
  4461. {
  4462.     int     rp;
  4463.     int     current_line;
  4464.     int     wordwidth ;
  4465.     bool turnon;
  4466.     unsigned short  nbpl;
  4467.     long4    rowsleft, word, wordweight, hbit, count, i, j, tl;
  4468.     long4    row[101] ;
  4469.     unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
  4470.     unsigned short  bp;
  4471.  
  4472.  
  4473.     if (ce->charsize == HUGE_SIZE)
  4474.         Fatal( "cannot process currently PK font patterns of that size!\n");
  4475.  
  4476.  
  4477.     current_line = 0;
  4478.     pkloc = (unsigned char *)ce->where.address.pixptr;
  4479.     dyn_f = (unsigned char)(ce->flag_byte >> 4);
  4480.     turnon = (bool)((ce->flag_byte & 8) == 8);
  4481.     wordwidth = (int)(ce->width + 31) >> 5 ;
  4482.     nbpl = ((int)(ce->width) +  7) >> 3;
  4483.  
  4484.     bitweight = 0 ;
  4485.     if (dyn_f == 14) {
  4486.         /*printf("<Get raster by bits@>\n");*/
  4487.         for (i = 1; i <= (long4)ce->height; i++) {
  4488.         word = 0 ;
  4489.         wordweight = 31 ;
  4490.         bp = 0;            /* Sowa */
  4491.  
  4492. #ifdef DRAWGLYPH
  4493.            printf("     |");
  4494. #endif
  4495.         for (j = 1; j <= (long4) ce->width; j++) {
  4496.             bool getbit;
  4497.             /* bp = 0;               SOWA */
  4498. /*******************************************begin Getbit *********/
  4499.             bitweight /= 2 ;
  4500.             if ( bitweight == 0 ) {
  4501.                 inputbyte = PKBYTE ;
  4502.                 bitweight = 128 ;
  4503.             }
  4504.             getbit = (bool)
  4505.              ( inputbyte >= bitweight ) ;
  4506.             if ( getbit )
  4507.                 inputbyte -= bitweight ;
  4508. /*********************************************end Getbit *********/
  4509.  
  4510.             if (getbit)
  4511.                 word += power[wordweight] ;
  4512.  
  4513.             wordweight --;
  4514.             if (wordweight == -1) {
  4515.  
  4516. #ifdef DRAWGLYPH
  4517.    { int k;
  4518.      for (k=31; k>=0; k--) {
  4519.          if ((power[k] & word)!=0) printf("M");
  4520.          else printf(".");
  4521.      }
  4522.    }
  4523. #endif
  4524.  
  4525.             OUTCHAR((word >> 24 & 0xFF));
  4526.             OUTCHAR((word >> 16 & 0xFF));
  4527.             OUTCHAR((word >> 8 & 0xFF));
  4528.             OUTCHAR((word    & 0xFF));
  4529.  
  4530.             word = 0 ;
  4531.             wordweight = 31 ;
  4532.             }
  4533.         }
  4534.         if (wordweight < 31) {
  4535. #ifdef COMMENT
  4536. #ifdef DRAWGLYPH
  4537.    { int k;
  4538.      for (k=15; k>=0; k--) {
  4539.         if ((power[k] & word)!=0) printf("Z");
  4540.         else printf(":");
  4541.      }
  4542.     }
  4543.     printf("|\n ----|");
  4544. #endif
  4545. #endif
  4546.  
  4547.             for (j = 3; j >= (wordwidth * 4 - (long4)nbpl);
  4548.             j--) {
  4549.  
  4550.                 OUTCHAR(((word >> (j << 3)) & 0xff));
  4551.  
  4552. #ifdef DRAWGLYPH
  4553.    { int k;
  4554.      for (k=7; k>=0; k--) {
  4555.         if ((power[k] & ((word >> (j << 3)) & 0xff))!=0) printf("M");
  4556.         else printf(".");
  4557.      }
  4558.    }
  4559. #endif
  4560.  
  4561.             }
  4562.         }
  4563.  
  4564.         if (raster) {
  4565.             RasterLine(ce, (unsigned int)nbpl,
  4566.                 current_line, raster_line_buf);
  4567.             current_line++;
  4568.         } else
  4569.             EMITL(bp, raster_line_buf);
  4570.  
  4571. #ifdef DRAWGLYPH
  4572.    printf("|\n");
  4573. #endif
  4574.         }
  4575.     } else {
  4576.         /* fprintf(stderr, "@<Create normally packed raster@>\n"); */
  4577.         rowsleft = (long4) ce->height ;
  4578.         hbit = (long4) ce->width ;
  4579.         repeatcount = 0 ;
  4580.         wordweight = 32 ;
  4581.         word = 0 ;
  4582.         rp = 1 ;
  4583.         while ( rowsleft > 0 ) {
  4584.         count = pk_packed_num() ;
  4585.         bp = 0;
  4586.  
  4587.         while (count > 0) {
  4588.             if ((count < wordweight) && (count < hbit)) {
  4589.             if (turnon)
  4590.                 word +=
  4591.                     gpower[wordweight] -
  4592.                     gpower[wordweight - count] ;
  4593.  
  4594.             hbit -= count ;
  4595.             wordweight -= count ;
  4596.             count = 0 ;
  4597.             } else if ((count >= hbit) && (hbit <=
  4598.             wordweight)) {
  4599.  
  4600.             if (turnon)
  4601.                 word +=
  4602.                     gpower[wordweight] -
  4603.                     gpower[wordweight - hbit] ;
  4604.  
  4605.             row[rp] = word ;
  4606.  
  4607.             /*fprintf(stderr, " @<Send row@> \n");*/
  4608.             for (i = 0; i <= (long4) repeatcount; i++) { int ii;
  4609.  
  4610. #ifdef DRAWGLYPH
  4611.   printf("***  |");
  4612. #endif
  4613.                 for (ii = 1; ii < wordwidth; ii++) {
  4614.                 tl = row[ii];
  4615.  
  4616.                 OUTCHAR((tl >> 24 & 0xFF));
  4617.                 OUTCHAR((tl >> 16 & 0xFF));
  4618.                 OUTCHAR((tl >> 8  & 0xFF));
  4619.                 OUTCHAR((tl       & 0xFF));
  4620.  
  4621. #ifdef DRAWGLYPH
  4622.    { int k;
  4623.      for (k=31; k>=0; k--)  {
  4624.          if ((power[k] & row[ii])!=0) printf("M");
  4625.          else printf(".");
  4626.      }
  4627.    }
  4628. #endif
  4629.                 }
  4630.                 tl = row[wordwidth];
  4631.                 for (j = 3; j >= (wordwidth *4 - (long4)nbpl);
  4632.                  j--) {
  4633.  
  4634.                  OUTCHAR(((tl >> (j << 3)) & 0xff));
  4635.  
  4636. #ifdef DRAWGLYPH
  4637.    { int k;
  4638.      for (k=7; k>=0; k--) {
  4639.          if ((power[k] & ((tl >> (j << 3)) & 0xff))!=0) printf("M");
  4640.          else printf(".");
  4641.      }
  4642.    }
  4643. #endif
  4644.                 }
  4645.  
  4646.                 if (raster) {
  4647.                     RasterLine(ce,
  4648.                     (unsigned int)nbpl,
  4649.                      current_line,
  4650.                      raster_line_buf);
  4651.                     current_line++;
  4652.                 } else
  4653.                     EMITL(bp, raster_line_buf);
  4654.  
  4655.                 bp = 0;
  4656.  
  4657. #ifdef DRAWGLYPH
  4658.    printf("|  ");
  4659.    for (j=1;j<=(long4)wordwidth;j++) printf("%02lX/",row[j]);
  4660.    printf(" raster=%d\n",raster);
  4661. #endif
  4662.             }
  4663.  
  4664.             rowsleft -=  (long4)repeatcount + 1 ;
  4665.             repeatcount = 0 ;
  4666.             rp = 1 ;
  4667.             word = 0 ;
  4668.             wordweight = 32 ;
  4669.             count -= hbit ;
  4670.             hbit = (long4)ce->width ;
  4671.             } else {
  4672.             if (turnon) word += gpower[wordweight] ;
  4673.             row[rp] = word ;
  4674.             rp = rp + 1 ;
  4675.             word = 0 ;
  4676.             count -= wordweight ;
  4677.             hbit -= wordweight ;
  4678.             wordweight = 32 ;
  4679.             }
  4680.         }   /* .....while count > 0 */
  4681.         if (turnon)
  4682.             turnon = _FALSE;
  4683.         else
  4684.             turnon = _TRUE;
  4685.         } /* ...... rowsleft > 0 */
  4686.         if ((rowsleft != 0) || (hbit != (long4)ce->width))
  4687.             Fatal("Bad pk file----more bits than required!\n");
  4688.     } /* .... create normally packed raster */
  4689. }
  4690.  
  4691.  
  4692. unsigned char   getnyb ()
  4693. {
  4694.     register unsigned char  temp ;
  4695.     if ( bitweight == 0 ) {
  4696.         inputbyte = PKBYTE ;
  4697.         bitweight = 16 ;
  4698.     }
  4699.     temp = inputbyte / bitweight ;
  4700.     inputbyte -= temp * bitweight ;
  4701.     bitweight /= 16 ;
  4702.     return ( temp ) ;
  4703. }
  4704.  
  4705.  
  4706. long4
  4707. pk_packed_num ()
  4708. { /*@<Packed number procedure@>= */
  4709.     register int    i;
  4710.     long4    j;
  4711.  
  4712.     i = (int)getnyb();
  4713.     if (i == 0) {
  4714.         do {
  4715.             j = (long4)getnyb();
  4716.             i++;
  4717.         } while (j == 0) ;
  4718.         while (i > 0) {
  4719.             j = j * 16 + (long4)getnyb() ;
  4720.             i--;
  4721.         };
  4722.         return (j - 15 + (13 - dyn_f) * 16 + dyn_f) ;
  4723.     } else if (i <= (int)dyn_f) {
  4724.         return ((long4)i);
  4725.     } else if (i < 14) {
  4726.         return ((i-(long4)dyn_f - 1) * 16 + (long4)getnyb() + dyn_f + 1);
  4727.     } else {
  4728.         if (i == 14) {
  4729.             repeatcount = (int) pk_packed_num() ;
  4730.         } else {
  4731.             repeatcount = 1 ;
  4732.         }
  4733.         /*     fprintf(stderr,"repeatcount = [%d]\n",repeatcount);    */
  4734.         return (pk_packed_num()) ;    /* tail end recursion !! */
  4735.     }
  4736. }
  4737. #endif  
  4738.  
  4739. #ifndef USEPXL
  4740. void bad_gf(n)
  4741.     int n;
  4742. {
  4743.     Fatal("Bad gf file, case %d\n",n);      /* See gf.c */
  4744. }
  4745. #endif
  4746. /*-->FormFeed*/
  4747. /**********************************************************************/
  4748. /*****************************  FormFeed ******************************/
  4749. /**********************************************************************/
  4750. void
  4751. FormFeed()
  4752. {
  4753.  
  4754. #ifdef IBM3812
  4755.     unsigned short pages;
  4756.     if ( (ndone == 0) && (FirstAlternate)){
  4757.         for (pages = 1; pages < ncopies; pages++) {
  4758.             PMPout(2, "\321\300"); /* PMP-command xD1C0 */
  4759.         }
  4760.         PMPout(2, "\321\100"); /* PMP-command xD140 */
  4761.     } else {
  4762.         for (pages = 1; pages < ncopies; pages++){
  4763.             PMPout(2, "\321\200"); /* PMP-command xD180 */
  4764.         }
  4765.         PMPout(2, "\321\0"); /* PMP-command xD100 */
  4766.     }
  4767. #endif
  4768. #ifdef LJ
  4769.     EMITC('\f');
  4770. #endif
  4771. }
  4772.