home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fonts 1 / freshfonts1.bin / programs / amiga / pastex / archives / dvi2lj-0.49.lha / dvi2xx.c < prev    next >
C/C++ Source or Header  |  1992-09-09  |  127KB  |  3,895 lines

  1. #define VERSION "0.49"
  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.  **********************************************************************
  67.  * Preprocessor switches:
  68.  *      #define DEBUG    for massive printing of trace information
  69.  *               when -d cmdline option specified
  70.  *      #define IBM3812  produce output for the IBM3812 pageprinter
  71.  *      #define LJ       produce output for the HP Laserjet+ or LJ II
  72.  *      #define LJ2P     produce output for the HP Laserjet LJ IIP, LJ III
  73.  *                       or LaserJet 2000
  74.  *      #define LJ_LARGE_FONT_MEMORY  large FONT Memory for LJ printer family
  75.  *      #define DRAWGLYPH draws PK-Glyphs on stderr
  76.  *      #define USEPXL   use PXL and PK fonts rather than gf fonts
  77.  */
  78. /**********************************************************************
  79.  ************************  Global Definitions  ************************
  80.  **********************************************************************/
  81. /* #define IBM3812 */
  82. /* #define LJ */
  83. /* #define DRAWGLYPH */
  84.  
  85. #include "config.h"
  86.  
  87. #ifdef unix
  88. #define OS "Unix"
  89. #define READ_BINARY     "r"
  90. #define WRITE_BINARY    "w"
  91. #define labs(x) abs(x)
  92. #endif
  93. #ifdef amiga
  94. #define OS "Amiga"
  95. #define READ_BINARY     "r"
  96. #define WRITE_BINARY    "w"
  97. #define labs(x) abs(x)
  98. #endif
  99. #ifdef MSDOS
  100. #define OS "MS-DOS"
  101. #define READ_BINARY     "rb"
  102. #define WRITE_BINARY    "wb"
  103. #define MSC5
  104. #endif
  105. #ifdef OS2
  106. #define OS "OS/2"
  107. #define READ_BINARY     "rb"
  108. #define WRITE_BINARY    "wb"
  109. #define MSC5
  110. #endif
  111.  
  112. #include "commands.h"
  113. #include <string.h>
  114. #include <signal.h>
  115. #include <stdio.h>
  116. #include <ctype.h>
  117. #include <fcntl.h>
  118. #ifdef MSDOS
  119. #include <dos.h>     /* only for binaryopen on device  */
  120. #endif
  121. #ifdef  unix
  122. #   ifndef AIX
  123. #include <limits.h>
  124. #endif
  125. #endif
  126.  
  127. #define  DVIFORMAT    2
  128. #define  UNKNOWN     -1
  129. #define  FIRSTFNTCHAR     0
  130.  
  131. #ifdef   OPEN_MAX                    /* ... in a friendly unix system  */
  132. #define  MAXOPEN    (OPEN_MAX - 8)
  133. #else
  134. #define  MAXOPEN          12     /* limit on number of open font files */
  135. #endif
  136. #define  NFNTCHARS       LASTFNTCHAR+1
  137. #define  STACK_SIZE      100     /* DVI-stack size                     */
  138. #define  NONEXISTANT     -1      /* offset for PXL files not found     */
  139. #define  NO_FILE        ((FILE *)-1)
  140. #define  NEW(A) ((A *)  malloc(sizeof(A)))
  141. #define  EQ(a,b)        (strcmp(a,b)==0)
  142. #define  MM_TO_PXL(x)   (int)(((x)*RESOLUTION*10)/254)
  143. #define  PT_TO_PXL(x)   (int)((long)((x)*RESOLUTION*100l)/7224)
  144. #define  PT_TO_DVI(x)   (long)((x)*65536l)
  145. #define  BOPENCMD fopen
  146. #define  BINOPEN(f) BOPENCMD(f,READ_BINARY)
  147. /* SMALL_SIZE characters are loaded into font storage of the printer   */
  148. /* LARGE_SIZE characters are rastered                                  */
  149. /* HUGE_SIZE characters are not loaded into the memory of the host     */
  150. #define  SMALL_SIZE (unsigned char) 0
  151. #define  LARGE_SIZE (unsigned char) 1
  152. #define  HUGE_SIZE  (unsigned char) 2
  153. #define  HUGE_CHAR_PATTERN 32767l
  154. #define  BYTES_PER_PIXEL_LINE 500    /* max number of bytes per pixel line */
  155.  
  156.  
  157. #define PK_POST 245
  158. #define PK_PRE 247
  159. #define PK_ID 89
  160.  
  161. /* to speedup the program a little: redefinition of PixRound and PutWord */
  162. /*#define PIXROUND(x,c) ((((double)x+(double)(c>>1))/(double)c)+0.5)*/
  163. #define PIXROUND(x,c) (((x)+c)/c)
  164. #define PUTWORD(w)  EMITC((char)(w>>8)&0xff); EMITC((char)w&0xff)
  165. /*************************************************************************/
  166. #define  EMIT            fprintf              /* output a formatted string   */
  167. #define  EMITB(len,b)   fwrite(b,1,len,outfp)  /* output binary data of len  */
  168. #define  EMITWORD(w)    PUTWORD((w))         /* output a 2 byte word of data */
  169.  
  170. #define  MoveOver(b)  h += (long) b
  171. #define  MoveDown(a)  v += (long) a
  172. #define  qfprintf if (!G_quiet) fprintf
  173. #define  qprintf  if (!G_quiet) printf
  174. #define  LARGER(a,b) (((a)>(b)) ? (a) : (b))
  175.  
  176. #ifdef IBM3812
  177. #define  PRINTER      "IBM 3812 pageprinter"
  178. #define  EMITC(c)      PMPoutC(c)               /* output a single character */
  179. #define  PMPcont(l)    PMPout(-1,(long)l)         /* next l bytes continuous */
  180. #define  PMPflush      PMPout(0l,"")                     /* flush PMP-buffer */
  181. #define  EMITL(l,d)    PMPout((int)l,d)      /* EMIT-logical: via PMP-buffer */
  182. #define  RESOLUTION    240
  183. #define  hconvRESOLUTION   240
  184. #define  vconvRESOLUTION   240
  185. #define  CHAR_WIDTH_LARGE  100       /*  limit for loading into printer font */
  186. #define  CHAR_HEIGTH_LARGE 127       /*  limit for loading into printer font */
  187. #define  OUTBUFSIZE     20000        /*   size of output buffer for PMP cmds */
  188.                       /*   has to be less max(signed int)     */
  189. #define  MAXFONTSTORAGE      130000l /* font storage in the 3812 pageprinter */
  190. #define  EMITFILE_EXTENSION    ".pmp"      /* default extension of emit file */
  191. #define  XDEFAULTOFF    RESOLUTION        /* y default offset on page 1 inch */
  192. #define  YDEFAULTOFF    RESOLUTION        /* y default offset on page 1 inch */
  193. #define  CHARSTRINGMAX  80                /* bufferlength for SetString      */
  194. #define  MAX_PAGE_WIDTH  2040
  195. #define  MAX_PAGE_HEIGHT 3360
  196. /**********************************************************************/
  197. /**************  Positioning for the 3812  ****************************/
  198. /**********************************************************************/
  199. #define VERT_HALF(n) ((short)(n+1>>1)-1)
  200. #define HOR_HALF(n)  ((short)(n>>1))
  201. #define MoveHor(n)  if ((n)!=0) { PMPcont(3); PMPout(1,"\342"); EMITWORD((n)); }
  202. #define MoveVert(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\343"); EMITWORD((n)); }
  203. #endif
  204.  
  205. #ifdef LJ
  206. #ifdef LJ2P
  207. #define  PRINTER       "HP LaserJet IIP"
  208. #else
  209. #define  PRINTER       "HP LaserJet"
  210. #endif LJ2P
  211. #define  RESOLUTION    300
  212. #define  hconvRESOLUTION   300
  213. #define  vconvRESOLUTION   300
  214. #ifdef LJ2P
  215. #define  CHAR_WIDTH_LARGE  16384     /* limit for loading into printer font */
  216. #define  CHAR_HEIGTH_LARGE 16384         /* y_offset reaches the same size! */
  217. #else   /* such as LJ+, LJ2 */
  218. #define  CHAR_WIDTH_LARGE  100       /* limit for loading into printer font */
  219. #define  CHAR_HEIGTH_LARGE 127           /* y_offset reaches the same size! */
  220. #endif
  221. #define  EMITFILE_EXTENSION    ".pcl"      /* default extension of emit file */
  222. #ifdef LJ_LARGE_FONT_MEMORY
  223. #define  MAX_FONTS_PER_PAGE 255         /* maximum number of fonts per page */
  224. #else
  225. #define  MAX_FONTS_PER_PAGE 16          /* maximum number of fonts per page */
  226. #endif
  227. #define  HANDLE_MAX_FONTS  255      /* max nr of fonts handled (rasterfont) */
  228. #define  FONTS_DOWNLOADABLE 32    /* max nr of fonts that can be downloaded */
  229. #define  MAXFONTSTORAGE (395l*1024l)                /* standard user memory */
  230. #define  EMITC(c)       putc(c,outfp)          /* output a single character */
  231. #define  EMITL(l,d)     EMITB(l,d)                  /* EMIT-logical = EMITB */
  232. #define  XDEFAULTOFF    RESOLUTION-54 /*x default offset on page 1 inch (LJ2)*/
  233. #define  YDEFAULTOFF    RESOLUTION+9    /* y default offset on page 1 inch */
  234. #define  max(x,y)       if ((y)>(x)) x = y
  235. #define  INT_ASCII(b,i) if (i == 0) b[0] = '\0'; else sprintf(b,"%hd",i)
  236. #endif
  237. /**********************************************************************/
  238. /***********************  external definitions  ***********************/
  239. /**********************************************************************/
  240. /*typedef  char    bool;*/
  241.  
  242. #ifndef unix
  243. #ifndef amiga
  244. long    access();
  245. FILE   *BOPENCMD();
  246. void    exit();
  247. int     fclose();
  248. int     fprintf();
  249. int     fseek();
  250. char   *index();
  251. int     printf();
  252. int     sscanf();
  253. int     strcmp();
  254. char   *strcpy();
  255. #ifdef MSC5
  256. unsigned int    strlen();
  257. #endif
  258. void    free();
  259. void    setbuf();
  260. #endif
  261. #endif
  262. char   *getenv();
  263.  
  264. #ifdef MSDOS
  265. int     intdos();
  266. #endif
  267.  
  268. #ifndef USEPXL
  269. /* interface to gf.c */
  270. extern FILE *gfin;
  271. extern int checksum;
  272. extern long tfm_wd[], char_pointer[];
  273. extern char char_exists[];
  274. extern int num_cols, num_rows, num_bytes, x_offset, y_offset;
  275. extern unsigned char bits[];
  276. extern int gf_font_max_m, gf_font_max_n, gf_font_min_n;
  277. extern int gettochar();
  278. extern void readbits();
  279. extern void readpost();
  280. extern void seekpost();
  281. extern int seekchar();
  282. #endif
  283.  
  284.  
  285. /**********************************************************************/
  286. /*************************  Global Procedures  ************************/
  287. /**********************************************************************/
  288. /* Note: Global procedures are declared here in alphabetical order, with
  289.    those which do not return values typed "void".  Their bodies occur in
  290.    alphabetical order following the main() procedure.  The names are
  291.    kept unique in the first 6 characters for portability. */
  292. double  ActualFactor();
  293. void    AllDone();
  294. #ifdef  MSDOS
  295. void    AssureBinary();  /* DOS and Microsoft C dependent !!! */
  296. #endif
  297. void    CopyFile();
  298. void    DecodeArgs();
  299. void    DoBop();
  300. long    DoConv();
  301. void    DoSpecial();
  302. void    EmitChar();
  303. void    Fatal();
  304. void    FindPostAmblePtr();
  305. void    FormFeed();
  306. void    GetBytes();
  307. void    GetFontDef();
  308. char    *GetKeyStr();
  309. bool    GetKeyVal();
  310. bool    IsSame();
  311. void    lcase();
  312. void    LoadAChar();
  313. long    NoSignExtend();
  314. /* see cautionary note in code, re arithmetic vs logical shifts */
  315. void    OpenFontFile();
  316. long    PixRound();
  317. void    PkRaster();
  318. void    PutWord();
  319. void    RasterLine();
  320. void    RasterChar();
  321. void    ReadFontDef();
  322. void    ReadPostAmble();
  323. void    SetChar();
  324. void    SetFntNum();
  325. void    SetPosn();
  326. void    SetRule();
  327. void    SetString();
  328. long    SignExtend();
  329. /* see cautionary note in code, re arithmetic vs logical shifts */
  330. void    SkipFontDef();
  331. void    Warning();
  332. unsigned char   skip_specials() ;
  333.  
  334. #ifdef IBM3812
  335. void    PMPout();
  336. void    PMPoutC();
  337. #endif
  338.  
  339. /**********************************************************************/
  340. /***********************  Font Data Structures  ***********************/
  341. /**********************************************************************/
  342.  
  343. struct char_entry {             /* character entry */
  344. #ifdef USEPXL
  345.     unsigned short  width, height;      /* width and height in pixels */
  346.     short   xOffset, yOffset, yyOffset; /* x offset and y offset in pixels*/
  347. #endif
  348.     struct {
  349.         bool isloaded;
  350.         union {
  351.             long    fileOffset;
  352.             long    *pixptr;
  353.         } address;
  354.     } where;
  355.     long    tfmw;             /* TFM width                 */
  356.     long    cw;               /* character width in pixels */
  357.     unsigned char   flag_byte;          /* for PK-files    */
  358.     unsigned char   charsize;
  359. };
  360. struct font_entry {    /* font entry */
  361.     long    k, c, s, d;
  362.     int     a, l;
  363.     char n[STRSIZE];          /* FNT_DEF command parameters           */
  364.     long    font_mag;         /* computed from FNT_DEF s and d parameters */
  365.     /*char psname[STRSIZE];*/ /* PostScript name of the font          */
  366.     char    name[STRSIZE];    /* full name of PXL file                */
  367.     FILE * font_file_id;      /* file identifier (NO_FILE if none)    */
  368. #ifdef USEPXL
  369.     long    magnification;    /* magnification read from PXL file     */
  370.     long    designsize;       /* design size read from PXL file       */
  371. #endif
  372.     struct char_entry ch[NFNTCHARS];   /* character information       */
  373.     struct font_entry *next;
  374.     unsigned short ncdl;      /* #of different chars actually downloaded */
  375.     unsigned short plusid;    /* Font id in Printer                    */
  376.     bool used_on_this_page;
  377.     enum PxlId {
  378.         id1001, id1002, pk89    } id;
  379. #ifdef LJ
  380.     unsigned short max_width, max_height, max_yoff;
  381. #endif
  382. };
  383.  
  384.  
  385. struct pixel_list {
  386.     FILE *pixel_file_id;    /* file identifier  */
  387.     int     use_count;      /* count of "opens" */
  388. };
  389. /**********************************************************************/
  390. /*************************  Global Variables  *************************/
  391. /**********************************************************************/
  392. long    FirstPage  = -1000000;  /* first page to print (uses count0)   */
  393. long    LastPage   = 1000000;   /* last page to print                  */
  394. long    PrintPages = 1000000;   /* nr of pages to print                */
  395. char    G_progname[STRSIZE];    /* program name                        */
  396. char    filename[STRSIZE];      /* DVI file name                       */
  397. char    rootname[STRSIZE];      /* DVI filename without extension      */
  398. char    *PXLpath = FONTAREA;    /* PXL path name for search            */
  399. char    *HeaderFileName = "";   /* file name & path of Headerfile      */
  400. char    *EmitFileName = "";     /* file name & path for output         */
  401. #ifdef IBM3812
  402. bool    FirstAlternate = FALSE; /* first page from alternate casette ? */
  403. #endif
  404. bool    Reverse = FALSE;        /* process DVI pages in reverse order? */
  405. bool    Landscape = FALSE;      /* print document in ladscape mode     */
  406. bool    ResetPrinter = TRUE;    /* reset printer at the begin of the job*/
  407. bool    DoublePage = FALSE;     /* printing on both sides of a page    */
  408. short   PageParity = 1;
  409. #ifdef LJ
  410. bool    PrintTestPage = FALSE;  /* print testpage with pagecounter after job */
  411. unsigned short pagesize = 0;    /* page size value                      */
  412. unsigned short pgsiz_dots = 0;  /* page size in dots (for rule-clipping)*/
  413. #endif
  414. short   G_errenc = 0;           /* has an error been encountered?      */
  415. bool    G_header = FALSE;       /* copy header file to output?         */
  416. bool    G_quiet = FALSE;        /* for quiet operation                 */
  417. bool    G_noverbatim = TRUE;    /* inform user about pxl-files used    */
  418. bool    G_nowarn = FALSE;       /* don't print out warnings            */
  419. short   x_origin = XDEFAULTOFF; /* x-origin in dots                    */
  420. short   y_origin = YDEFAULTOFF; /* y-origin in dots                    */
  421. short   x_goffset;              /* global x-offset in dots             */
  422. short   y_goffset;              /* global y-offset in dots             */
  423. unsigned short ncopies = 1;     /* number of copies to print           */
  424. long    hconv, vconv;           /* converts DVI units to pixels        */
  425. long    den;                    /* denominator specified in preamble   */
  426. long    num;                    /* numerator specified in preamble     */
  427. long    h;                      /* current horizontal position         */
  428. long    hh = 0;                 /* current h on device                 */
  429. long    v;                      /* current vertical position           */
  430. long    vv = 0;                 /* current v on device                 */
  431. long    mag;                    /* magnification specified in preamble */
  432. long    usermag = 0;            /* user specified magnification        */
  433. int     ndone = 0;              /* number of pages converted           */
  434. int     nopen = 0;              /* number of open PXL files            */
  435. FILE  *outfp = NULL;            /* output file                         */
  436. FILE  *pxlfp;                   /* PXL file pointer                    */
  437. FILE  *dvifp  = NULL;           /* DVI file pointer                    */
  438. struct font_entry *prevfont = NULL; /* font_entry pointer previous font*/
  439. struct font_entry *fontptr;     /* font_entry pointer                  */
  440. struct font_entry *hfontptr = NULL; /* font_entry pointer              */
  441. struct font_entry *pfontptr = NULL; /* previous font_entry pointer     */
  442. struct pixel_list pixel_files[MAXOPEN+1]; /* list of open PXL files    */
  443. long    postambleptr;           /* Pointer to the postamble            */
  444. long    ppagep;                 /* previous page pointer               */
  445. static int      last_ry = UNKNOWN;      /* last y-position on page     */
  446. static int      last_rx = UNKNOWN;      /* last x-position on page     */
  447. long   StartPrintPages;         /* notpad for double paged output      */
  448. int    WouldPrint    = 0;
  449. bool   ZeroPage = FALSE;        /* Document starts with a Zero Page    */
  450. bool   EvenPage = FALSE;        /* Document starts with an even Page   */
  451. long   LastPtobePrinted = 0;
  452. int    G_ncdl = 0;
  453.  
  454. long    allocated_storage = 0; /* size of mallocated storage (statistics) */
  455. long    power[32] ;
  456. long    gpower[33] ;
  457.  
  458.  
  459. #ifdef DEBUG
  460. bool Debug = FALSE;
  461. #endif
  462.  
  463. #ifdef LJ
  464. int     fonts_used_on_this_page = MAX_FONTS_PER_PAGE+1;
  465. char    rasterfont[HANDLE_MAX_FONTS];
  466.     /* raster if fonts/page>MAX_FONTS_PER_PAGE*/
  467. #endif
  468.  
  469. long    used_fontstorage = 0;
  470.  
  471. #ifdef IBM3812
  472. char    PMPformat[20];
  473. char    CharString[CHARSTRINGMAX];
  474. unsigned int CharStringPos = 0;
  475. #define CharStringOut \
  476.     if (CharStringPos>0) { \
  477.         PMPcont(CharStringPos+1);\
  478.         PMPoutC((unsigned char)CharStringPos);\
  479.         PMPout(CharStringPos, CharString); \
  480.         CharStringPos=0; }
  481. #endif
  482.  
  483. #ifdef TIMING
  484. /************************timing stuff*********************/
  485. #include <sys/timeb.h>
  486. void ftime();
  487. struct timeb timebuffer;
  488. double  start_time;
  489. #endif
  490.  
  491.  
  492. /**********************************************************************/
  493. /*******************************  main  *******************************/
  494. /**********************************************************************/
  495. void
  496. main(argc, argv)
  497. int     argc;
  498. char    *argv[];
  499. {
  500.     struct stack_entry {  /* stack entry */
  501.         long    h, v, w, x, y, z;  /* what's on stack */
  502.     };
  503.     short   command;          /* current command                         */
  504.     long    count[10];        /* the 10 counters at begining of each page*/
  505.     long    cpagep;           /* current page pointer                    */
  506.     bool Emitting = FALSE;    /* outputting typsetting instructions?     */
  507.     int     i;                /* command parameter; loop index           */
  508.     int     k;                /* temporary parameter                     */
  509.     char    n[STRSIZE];       /* command parameter                       */
  510.     int     PassNo = 0;       /* which pass over the DVI page are we on? */
  511.     bool SkipMode = FALSE;    /* in skip mode flag                       */
  512.     int     sp;               /* stack pointer                           */
  513.     struct stack_entry stack[STACK_SIZE];  /* stack                      */
  514.     char    SpecialStr[STRSIZE]; /* "\special" strings                   */
  515.     long    val, val2;        /* temporarys to hold command information  */
  516.     long    w;                /* current horizontal spacing              */
  517.     long    x;                /* current horizontal spacing              */
  518.     long    y;                /* current vertical spacing                */
  519.     long    z;                /* current vertical spacing                */
  520.  
  521.  
  522.     extern  char *sys_errlist[];
  523.     extern  int     errno;
  524.  
  525. /*    setbuf(stderr, NULL);    */        /* DJB: WHY?  Just slow! */
  526.     (void) strcpy(G_progname, argv[0]);
  527.     DecodeArgs( argc, argv );
  528.  
  529.     power [ 0 ] = 1 ;
  530.     for ( i = 1 ; i <= 31 ; i ++)
  531.         power [ i ] = power [ i - 1 ] << 1 ;
  532.     gpower[0] = 0l ;
  533.     for ( i = 1 ; i <= 32 ; i ++)
  534.         gpower[i] = gpower[i - 1] + power[i - 1] ;
  535.  
  536.     if ((i = (int) NoSignExtend(dvifp, 1)) != PRE)  {
  537.         Fatal(
  538.         "%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n",
  539.                 G_progname);
  540.     }
  541.     i = (int) SignExtend(dvifp, 1);
  542.     if (i != DVIFORMAT)  {
  543.         Fatal( "%s: DVI format = %d, can only process DVI format %d files\n\n",
  544.                 G_progname, i, DVIFORMAT);
  545.     }
  546.  
  547.     if (*EmitFileName == '-')
  548.         outfp = stdout;
  549.     else
  550.         if ((outfp = fopen(EmitFileName, WRITE_BINARY)) == NULL)
  551.         Fatal("opening output file: fopen(%s) : %s",
  552.             EmitFileName,sys_errlist[errno]);
  553.  
  554. #ifdef MSDOS
  555.     AssureBinary(outfp);
  556. #endif
  557.  
  558. #ifdef TIMING
  559.     ftime(&timebuffer);
  560.     start_time = (timebuffer.time) + (timebuffer.millitm) / 1000.0;
  561. #endif
  562.  
  563.     /* it is important that these be the very first things output !!! */
  564.     if ( G_header )
  565.         CopyFile( HeaderFileName );
  566.  
  567.     /*****************************/
  568.     /*for( i0=0; i0<nif; i0++ )  */    /* copy all included files */
  569.     /*    CopyFile( Ifile[i0] ); */
  570.     /*****************************/
  571.  
  572. #ifdef IBM3812
  573.     PMPout(3, "\307\310\366");          /* unload all fonts and macros */
  574.     EMITWORD(MAX_PAGE_WIDTH);
  575.     EMITWORD(MAX_PAGE_HEIGHT);
  576.     if (Landscape)
  577.         PMPout(2, "\322\1");
  578. #endif
  579. #ifdef LJ
  580.     if (ResetPrinter)
  581.         EMIT(outfp, "\033E");
  582.     if (Landscape)
  583.         EMIT(outfp, "\033&l1O\033*rF");
  584.     if (pagesize>0)
  585.         EMIT(outfp, "\033&l%hdaE\033&aL",pagesize);
  586.     else
  587.         EMIT(outfp, "\033&lE\033&aL");
  588.  
  589.     if (ncopies>1)
  590.         EMIT(outfp, "\033&l%hdX",ncopies);
  591. #endif
  592.     if (DoublePage) {
  593.          StartPrintPages = PrintPages;
  594. #ifdef IBM3812
  595.          Reverse = (bool)!Reverse; /* perverse and strange */
  596. #endif
  597.  
  598.     }
  599.     if (Reverse) {
  600. #ifdef DEBUG
  601.         if (Debug)
  602.               fprintf(stderr, "reverse\n");
  603. #endif
  604.         ReadPostAmble(TRUE);
  605.         fseek(dvifp, ppagep, 0);
  606.     } else {
  607.         ReadPostAmble(TRUE);
  608.         fseek(dvifp,  14l, 0);
  609.         k = (int) NoSignExtend(dvifp, 1);
  610.         GetBytes(dvifp, n, k);
  611.     }
  612.     PassNo = 0;
  613.  
  614.     while (TRUE)  {
  615.         command = (short) NoSignExtend(dvifp, 1)   ;
  616. #ifdef DEBUG
  617.         if (Debug)
  618.                fprintf(stderr,"CMD:\t%d\n", command);
  619. #endif
  620.         switch (command)  {
  621.         case SET1:
  622.         case SET2:
  623.         case SET3:
  624.         case SET4:
  625.             val = NoSignExtend(dvifp, (int) command - SET1 + 1);
  626.             if (!SkipMode)
  627.                 SetChar(val, command, PassNo, TRUE,FALSE);
  628.             break;
  629.         case SET_RULE:
  630.             val = NoSignExtend(dvifp, 4);
  631.             val2 = NoSignExtend(dvifp, 4);
  632.             if (Emitting)
  633.                 SetRule(val, val2, 1);
  634.             break;
  635.         case PUT1:
  636.         case PUT2:
  637.         case PUT3:
  638.         case PUT4:
  639.             val = NoSignExtend(dvifp, (int) command - PUT1 + 1);
  640.             if (!SkipMode)
  641.                 SetChar(val, command, PassNo, TRUE,FALSE);
  642.             break;
  643.         case PUT_RULE:
  644.             val = NoSignExtend(dvifp, 4);
  645.             val2 = NoSignExtend(dvifp, 4);
  646.             if (Emitting)
  647.                 SetRule(val, val2, 0);
  648.             break;
  649.         case NOP:
  650.             break;
  651.         case BOP:
  652.             cpagep = ftell(dvifp) - 1;
  653.             for (i = 0; i <= 9; i++)
  654.                 count[i] = NoSignExtend(dvifp, 4);
  655.             ppagep = NoSignExtend(dvifp, 4);
  656.             h = v = w = x = y = z = 0;
  657.             hh = vv = 0;
  658.             sp = 0;
  659.             fontptr = NULL;
  660.             prevfont = NULL;
  661.             DoBop();
  662.             if ( count[0] < FirstPage || count[0] > LastPage )
  663.                 SkipMode = TRUE;
  664.             else
  665.                 SkipMode = FALSE;
  666.             if (DoublePage && !SkipMode) {
  667.                if (PassNo == 0) {
  668.                   LastPtobePrinted=count[0];
  669.                   if (!Reverse && (WouldPrint == 0)) {
  670.                       if (count[0] == 0l) {
  671.                          ZeroPage = TRUE;
  672.                          EvenPage = FALSE;
  673.                       }
  674.                       else {
  675.                          EvenPage = (bool) ((int)count[0]%2 == 0);
  676.  
  677.                          if (EvenPage && PageParity==1) {
  678.                            WouldPrint ++;
  679.                            qfprintf(stderr,"[EvenPage] ");
  680.                            FormFeed();
  681.                          }
  682.                       }
  683.                   }
  684.                   WouldPrint ++;
  685. /*
  686.     printf("doublepage %d, Reverse %d, WouldPrint %d, fpZ %d\n",
  687.         (int)DoublePage, (int)Reverse, (int)WouldPrint, (int)ZeroPage);
  688. */
  689.                }
  690.                SkipMode =
  691.                    (bool)(PageParity != (short)(count[0]%2));
  692.  
  693.                if (count[0]==0l) SkipMode=(bool)!SkipMode;
  694.             }
  695.             Emitting = (bool)((PassNo != 0) && !SkipMode);
  696.             if ( !SkipMode ) {
  697.                 if ( PassNo == 0)
  698.         {
  699.                     qfprintf(stderr, "[%ld", count[0]);
  700. /* DJB */        fflush(stderr);
  701.         }
  702.             }
  703.             break;
  704.         case EOP:
  705.             if ( !SkipMode ) {
  706.                 if ( PassNo == 0 ) {
  707.                     /* start second pass on current page */
  708.                     fseek(dvifp, cpagep, 0);
  709.                     PassNo = 1;
  710.                 } else {
  711.                    /* end of second pass, and of page processing */
  712.  
  713.                     last_ry = UNKNOWN;
  714.                     FormFeed();
  715.                     ++ndone;
  716.  
  717.                     qfprintf(stderr, "] ");
  718. /* DJB */        fflush(stderr);
  719.                     if ( (ndone % 10) == 0 )
  720.                           qfprintf(stderr, "\n");
  721.  
  722.                     if (DoublePage) --PrintPages;
  723.                     if (--PrintPages < 1) AllDone(TRUE);
  724.                     PassNo = 0;
  725.                 }
  726.             } else
  727.                 PassNo = 0;
  728.  
  729.             if ( PassNo == 0 && Reverse ) {
  730.                 if ( ppagep > 0 )
  731.                     fseek(dvifp, ppagep, 0);
  732.                 else {
  733.                    if (DoublePage && !SkipMode)
  734.                      ZeroPage = (bool)(count[0]==0l);
  735.  
  736.                    if (ZeroPage)
  737.                      EvenPage = FALSE;
  738.                    else
  739.                      EvenPage = (bool) ((int)LastPtobePrinted%2 == 0);
  740.  
  741.                    AllDone(FALSE);
  742.                 }
  743.             }
  744.             break;
  745.         case PUSH:
  746.             if (sp >= STACK_SIZE)
  747.                 Fatal("stack overflow");
  748.             stack[sp].h = h;
  749.             stack[sp].v = v;
  750.             stack[sp].w = w;
  751.             stack[sp].x = x;
  752.             stack[sp].y = y;
  753.             stack[sp].z = z;
  754.             sp++;
  755.             break;
  756.         case POP:
  757.             --sp;
  758.             if (sp < 0)
  759.                 Fatal("stack underflow");
  760.             h = stack[sp].h;
  761.             v = stack[sp].v;
  762.             w = stack[sp].w;
  763.             x = stack[sp].x;
  764.             y = stack[sp].y;
  765.             z = stack[sp].z;
  766.             break;
  767.         case RIGHT1:
  768.         case RIGHT2:
  769.         case RIGHT3:
  770.         case RIGHT4:
  771.             val = SignExtend(dvifp, (int) command - RIGHT1 + 1);
  772.             if (Emitting)
  773.                 MoveOver(val);
  774.             break;
  775.         case W0:
  776.             if (Emitting)
  777.                 MoveOver(w);
  778.             break;
  779.         case W1:
  780.         case W2:
  781.         case W3:
  782.         case W4:
  783.             w = SignExtend(dvifp, (int)command - W1 + 1);
  784.             if (Emitting)
  785.                 MoveOver(w);
  786.             break;
  787.         case X0:
  788.             if (Emitting)
  789.                 MoveOver(x);
  790.             break;
  791.         case X1:
  792.         case X2:
  793.         case X3:
  794.         case X4:
  795.             x = SignExtend(dvifp, (int)command - X1 + 1);
  796.             if (Emitting)
  797.                 MoveOver(x);
  798.             break;
  799.         case DOWN1:
  800.         case DOWN2:
  801.         case DOWN3:
  802.         case DOWN4:
  803.             val = SignExtend(dvifp, (int)command - DOWN1 + 1);
  804.             if (Emitting)
  805.                 MoveDown(val);
  806.             break;
  807.         case Y0:
  808.             if (Emitting)
  809.                 MoveDown(y);
  810.             break;
  811.         case Y1:
  812.         case Y2:
  813.         case Y3:
  814.         case Y4:
  815.             y = SignExtend(dvifp, (int)command - Y1 + 1);
  816.             if (Emitting)
  817.                 MoveDown(y);
  818.             break;
  819.         case Z0:
  820.             if (Emitting)
  821.                 MoveDown(z);
  822.             break;
  823.         case Z1:
  824.         case Z2:
  825.         case Z3:
  826.         case Z4:
  827.             z = SignExtend(dvifp, (int)command - Z1 + 1);
  828.             if (Emitting)
  829.                 MoveDown(z);
  830.             break;
  831.         case FNT1:
  832.         case FNT2:
  833.         case FNT3:
  834.         case FNT4:
  835.             if (!SkipMode) {
  836.                 SetFntNum(NoSignExtend(dvifp, (int)command -FNT1 +1),Emitting);
  837.             }
  838.             break;
  839.         case XXX1:
  840.         case XXX2:
  841.         case XXX3:
  842.         case XXX4:
  843.             k = (int) NoSignExtend(dvifp, (int)command - XXX1 + 1);
  844.             GetBytes(dvifp, SpecialStr, k);
  845.             if (Emitting)
  846.                 DoSpecial(SpecialStr, k);
  847.             break;
  848.         case FNT_DEF1:
  849.         case FNT_DEF2:
  850.         case FNT_DEF3:
  851.         case FNT_DEF4:
  852.             k = (int) NoSignExtend(dvifp, (int)command - FNT_DEF1 + 1);
  853.             SkipFontDef();    /* SkipFontDef(k); */
  854.             break;
  855.         case PRE:
  856.             Fatal("PRE occurs within file");
  857.             break;
  858.         case POST:
  859.             AllDone(FALSE);
  860.             PassNo = 0;
  861.             break;
  862.         case POST_POST:
  863.             Fatal("POST_POST with no preceding POST");
  864.             break;
  865.         default:
  866.             if (command >= FONT_00 && command <= FONT_63) {
  867.                 if (!SkipMode)
  868.                     SetFntNum((long) command - FONT_00, Emitting);
  869.             } else if (command >= SETC_000 && command <= SETC_127) {
  870.                 if (!SkipMode) {
  871.                     SetString(command, PassNo);
  872.                 }
  873.             } else
  874.                 Fatal("%d is an undefined command", command);
  875.             break;
  876.         }
  877.     } /* while TRUE */
  878. }
  879.  
  880.  
  881. /*-->ActualFactor*/
  882. /**********************************************************************/
  883. /**************************  ActualFactor  ****************************/
  884. /**********************************************************************/
  885. double  /* compute the actual size factor given the approximation */
  886. ActualFactor(unmodsize)
  887. long    unmodsize;                 /* actually factor * 1000 */
  888. {
  889.     double  realsize;     /* the actual magnification factor */
  890.     realsize = (double)unmodsize / 1000.0;
  891.     if (abs((int)(unmodsize - 1095l))<2)
  892.         realsize = 1.095445115; /*stephalf*/
  893.     else if (abs((int)(unmodsize - 1315l))<2)
  894.         realsize = 1.31453414; /*stepihalf*/
  895.     else if (abs((int)(unmodsize - 1577l))<2)
  896.         realsize = 1.57744097; /*stepiihalf*/
  897.     else if (abs((int)(unmodsize - 1893l))<2)
  898.         realsize = 1.89292916; /*stepiiihalf*/
  899.     else if (abs((int)(unmodsize - 2074l))<2)
  900.         realsize = 2.0736;   /*stepiv*/
  901.     else if (abs((int)(unmodsize - 2488l))<2)
  902.         realsize = 2.48832;  /*stepv*/
  903.     else if (abs((int)(unmodsize - 2986l))<2)
  904.         realsize = 2.985984; /*stepvi*/
  905.     /* the remaining magnification steps are represented with sufficient
  906.        accuracy already */
  907.     return(realsize);
  908. }
  909.  
  910.  
  911. /*-->AllDone*/
  912. /**********************************************************************/
  913. /****************************** AllDone  ******************************/
  914. /**********************************************************************/
  915. void
  916. AllDone(PFlag)
  917. bool PFlag;
  918. {
  919.     double  time;
  920.  
  921.     if (DoublePage && (PageParity==1)) { /* Shall we go around again?*/
  922.         int k,rc;
  923.         char    n[STRSIZE];
  924.  
  925.         if (EvenPage && Reverse) {
  926.             WouldPrint ++;
  927.             qfprintf(stderr,"[EvenPage] ");
  928.             FormFeed();
  929.         }
  930. #ifdef LJ
  931.         Reverse = (bool)!Reverse;
  932. #endif
  933.         if (Reverse) {
  934.             if (!PFlag) {
  935.                fseek (dvifp, postambleptr, 0);
  936.                (void) NoSignExtend(dvifp, 1);
  937.                ppagep = NoSignExtend(dvifp, 4);
  938.             }
  939.             fseek(dvifp, ppagep, 0);
  940.         } else {
  941.             fseek(dvifp,  14l, 0);
  942.         k = (int) NoSignExtend(dvifp, 1);
  943.         GetBytes(dvifp, n, k);
  944.         }
  945.  
  946.  
  947. #ifdef LJ
  948.         EMIT(outfp, "\033&l2H"); /* Manual Feed */
  949. #endif
  950.         qfprintf(stderr,"\n----------------------starting second pass\n");
  951.  
  952. #ifdef IBM3812
  953.         PMPout(6,"\326\001\305\300\326\252");
  954.         /* set display; ring bell; stop; clear display */
  955.         PMPflush;
  956. #endif
  957.         if (Reverse) {
  958.         if (ZeroPage) WouldPrint++;
  959.         if ((WouldPrint%2) == 1) {
  960.             qfprintf(stderr,"[Padding] ");
  961.             FormFeed();
  962.         }
  963.         }
  964.         WouldPrint = 0;
  965.         if (!Reverse && ZeroPage) {
  966.         WouldPrint++;
  967.         qfprintf(stderr,"[ZeroPage] ");
  968.         FormFeed();
  969.         }
  970.         PageParity = 0;
  971.         PrintPages = StartPrintPages;
  972.         return;
  973.     }
  974.  
  975.     if (EvenPage && DoublePage && !Reverse) WouldPrint++;
  976.  
  977.     if (DoublePage) {
  978.         if (Reverse) {
  979.         if (ZeroPage) {
  980.             WouldPrint ++;
  981.             qfprintf(stderr,"[ZeroPage] ");
  982.             FormFeed();
  983.         }
  984.         }
  985.         else if ((WouldPrint%2) != 0) {
  986.             qfprintf(stderr,"[Padding] ");
  987.             FormFeed();
  988.         }
  989.     }
  990.  
  991. #ifdef IBM3812
  992.     PMPout(10, "\373\010PMP.init");  /* re-init printer  */
  993.     PMPflush;
  994.  
  995.     if (used_fontstorage > MAXFONTSTORAGE) {
  996.         Warning("\n\7used font_storage of %s: %ld Bytes (of %ld)\7",
  997.             PRINTER, used_fontstorage, MAXFONTSTORAGE);
  998.         Warning("Try to format file in separate runs!");
  999.     } else
  1000.         qfprintf(stderr,
  1001.            "\nAll done, used font_storage of %s: %ld Bytes (of %ld)",
  1002.              PRINTER, used_fontstorage, MAXFONTSTORAGE);
  1003. #endif
  1004. #ifdef LJ
  1005.     qfprintf(stderr, "\nAll done, used font_storage of %s: %ld Bytes",
  1006.              PRINTER, used_fontstorage);
  1007.     EMIT(outfp, "\033E");
  1008.     if (PrintTestPage) EMIT(outfp, "\033z");
  1009. #endif
  1010.  
  1011.     if (!G_quiet) {
  1012.         fprintf(stderr,"\nDynamically allocated storage: %ld Bytes \n",
  1013.                     allocated_storage);
  1014.         fprintf(stderr,"%d characters downloaded as soft fonts\n", G_ncdl);
  1015.  
  1016. #ifdef TIMING
  1017.         ftime(&timebuffer);
  1018.         time = ((timebuffer.time) + (timebuffer.millitm) / 1000.0) -start_time;
  1019.  
  1020.         if (ndone > 0) {
  1021.             fprintf(stderr,
  1022.            "Time of complete run: %.2f seconds, %d page(s), %.2f seconds/page",
  1023.                       time, ndone, time / ndone);
  1024.             fprintf(stderr," (%.2f ppm)\n",(ndone * 60) / time);
  1025.         }
  1026.         fprintf(stderr,"\n");
  1027. #endif
  1028.     }
  1029.  
  1030.     exit(G_errenc);
  1031. }
  1032.  
  1033.  
  1034. /*-->CopyFile*/   /* copy a file straight through to output */
  1035. /*********************************************************************/
  1036. /***************************** CopyFile ******************************/
  1037. /*********************************************************************/
  1038. void
  1039. CopyFile( str )
  1040. char    *str;
  1041. {
  1042.     FILE    * spfp;
  1043.     char    t;
  1044.     if ( (spfp = BINOPEN(str)) == NULL ) {
  1045.         Warning("Unable to open file %s", str );
  1046.         return;
  1047.     }
  1048.     qfprintf(stderr," [%s", str);
  1049.     for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
  1050.         putc(t, outfp);
  1051.     fclose(spfp);
  1052.     qfprintf(stderr,"]");
  1053.     fflush(stderr);        /* DJB */
  1054. }
  1055.  
  1056.  
  1057. /*-->DecodeArgs*/
  1058. /*********************************************************************/
  1059. /***************************** DecodeArgs ****************************/
  1060. /*********************************************************************/
  1061. void
  1062. DecodeArgs( argc, argv )
  1063. int     argc;
  1064. char    *argv[];
  1065. {
  1066.     int     argind;            /* argument index for flags      */
  1067.     char    curarea[STRSIZE];  /* current file area             */
  1068.     char    curname[STRSIZE];  /* current file name             */
  1069.     char    *tcp, *tcp1;       /* temporary character pointers  */
  1070.     char    *this_arg;
  1071.     double  x_offset=0.0, y_offset=0.0;
  1072.  
  1073.     if ((tcp = getenv("TEXPXL")) != NULL) PXLpath = tcp;
  1074.  
  1075.     argind = 1;
  1076.     while (argind < argc) {
  1077.         tcp = argv[argind];
  1078.         if (*tcp == '-') {
  1079.             ++tcp;
  1080.             switch (*tcp) {
  1081.             case 'a':       /* a selects different pxl font area */
  1082.                 PXLpath = ++tcp;
  1083.                 break;
  1084. #ifdef IBM3812
  1085.             case 'b':       /* first page from alternate casette */
  1086.                 FirstAlternate = TRUE;
  1087.                 break;
  1088. #endif
  1089.             case 'c':       /* number of copies to print */
  1090.                 if ( sscanf(tcp + 1, "%hd", &ncopies) != 1 )
  1091.                    Fatal("Argument of -c is not a valid integer\n");
  1092.                 if (ncopies<1) {
  1093.                   Warning("argument of -c < 1; set to 1!");
  1094.                   ncopies=1;
  1095.                 }
  1096.                 break;
  1097. #ifdef DEBUG
  1098.             case 'd':       /* d selects Debug output */
  1099.                 Debug = TRUE;
  1100.                 break;
  1101. #endif
  1102.             case 'D':       /* D selects DoublePage  */
  1103.                 DoublePage = TRUE;
  1104.                 break;
  1105.  
  1106.             case 'e':       /* emit file is specified */
  1107.                 EmitFileName = ++tcp;
  1108. #ifdef MSDOS
  1109.                 /* delete trailing ':' (causing hangup) */
  1110.                 if (EmitFileName[strlen(EmitFileName)-1] == ':')
  1111.                     EmitFileName[strlen(EmitFileName)-1] = '\0';
  1112. #endif
  1113. #ifdef OS2  /* repeated to avoid problems with stupid c preprocessors  */
  1114.                 /* delete trailing ':' (causing hangup) */
  1115.                 if (EmitFileName[strlen(EmitFileName)-1] == ':')
  1116.                     EmitFileName[strlen(EmitFileName)-1] = '\0';
  1117. #endif
  1118.                 break;
  1119.             case 'f':       /* next arg is starting pagenumber */
  1120.                 if ( sscanf(tcp + 1, "%ld", &FirstPage) != 1 )
  1121.                     Fatal("Argument is not a valid integer\n");
  1122.                 break;
  1123. #ifdef LJ
  1124.             case 'g':       /* do not reset printer (go) */
  1125.                 ResetPrinter = FALSE;
  1126.                 break;
  1127. #endif
  1128.             case 'h':     /* copy header file through to output  */
  1129.                 HeaderFileName = ++tcp;
  1130.                 G_header = TRUE;
  1131.                 break;
  1132. #if defined(LJ2P) || defined(IBM3812)
  1133.             case 'l':       /* landscape  */
  1134.                 Landscape = TRUE;
  1135.                 break;
  1136. #endif
  1137.             case 'x':       /* specify x-offset */
  1138.                 this_arg = 0;
  1139.                 if (!(*++tcp)) {
  1140.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1141.                 } else {
  1142.                     this_arg = tcp;
  1143.                 }
  1144.                 if (!this_arg
  1145.                      || sscanf(this_arg,"%lf", &x_offset) != 1)
  1146.          Fatal("Argument of -x is not a valid floating point number\n");
  1147.                 break;
  1148.             case 'y':       /* specify y-offset */
  1149.                 this_arg = 0;
  1150.                 if (!(*++tcp)) {
  1151.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1152.                 } else {
  1153.                     this_arg = tcp;
  1154.                 }
  1155.                 if (!this_arg || sscanf(this_arg, "%lf", &y_offset) != 1)
  1156.                 Fatal("Argument of -y is not a valid floating point number\n");
  1157.                 break;
  1158.             case 'X':       /* specify X-origin in dots */
  1159.                 this_arg = 0;
  1160.                 if (!(*++tcp)) {
  1161.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1162.                 } else {
  1163.                     this_arg = tcp;
  1164.                 }
  1165.                 if (!this_arg || sscanf(this_arg,"%hd", &x_origin) != 1)
  1166.                    Fatal("Argument of -X is not a valid integer\n");
  1167.                 break;
  1168.             case 'Y':       /* specify Y-origin in dots */
  1169.                 this_arg = 0;
  1170.                 if (!(*++tcp)) {
  1171.                     this_arg = (++argind >= argc ? 0 : argv[argind]);
  1172.                 } else {
  1173.                     this_arg = tcp;
  1174.                 }
  1175.                 if (!this_arg ||
  1176.                      sscanf(this_arg, "%hd", &y_origin) != 1)
  1177.                         Fatal("Argument of -Y is not a valid integer\n");
  1178.                 break;
  1179.             case 'm':       /* specify magnification to use */
  1180.                 switch ( (*++tcp) ) {
  1181.                 case '#':
  1182.                      /* next arg is a magnification to use */
  1183.                     if ( sscanf(tcp + 1, "%ld", &usermag) != 1 )
  1184.                        Fatal("Argument of mag is not a valid integer\n");
  1185.                     break;
  1186.                 case '0':
  1187.                     usermag = 1000;
  1188.                     break;
  1189.                 case 'h':
  1190.                 case 'H':
  1191.                     usermag = 1095;
  1192.                     break;
  1193.                 case '1':
  1194.                     usermag = 1200;
  1195.                     break;
  1196.                 case 'q':
  1197.                     usermag = 1250;
  1198.                     break;
  1199.                 case '2':
  1200.                     usermag = 1440;
  1201.                     break;
  1202.                 case '3':
  1203.                     usermag = 1728;
  1204.                     break;
  1205.                 case '4':
  1206.                     usermag = 2074;
  1207.                     break;
  1208.                 case '5':
  1209.                     usermag = 2488;
  1210.                     break;
  1211.                 default:
  1212.                     Fatal("%c is a bad mag step\n", *tcp);
  1213.                 }
  1214.                 break;
  1215. #ifdef SUPERCOMMENT
  1216.             case 'o':     /* PostScript command to send */
  1217.                 if ( ++argind >= argc )
  1218.                     Fatal("No argument following -o\n", 0);
  1219.                 PScmd[nps++] = argv[argind];
  1220.                 break;
  1221. #endif
  1222.             case 'p':       /* print n pages  */
  1223.                 if ( sscanf(tcp + 1, "%ld", &PrintPages) != 1 )
  1224.                     Fatal("Argument is not a valid integer\n");
  1225.                 if (PrintPages < 1)
  1226.                   Fatal("Argument of -p must be greater than 0\n");
  1227.                 break;
  1228.             case 'q':       /* quiet operation */
  1229.                 G_quiet = TRUE;
  1230.                 break;
  1231.             case 'r':       /* switch order to process pages */
  1232.                 Reverse = (bool)(!Reverse);
  1233.                 break;
  1234. #ifdef LJ
  1235.             case 's':       /* specify X-origin in dots */
  1236.                 this_arg = 0;
  1237.                 if (!(*++tcp)) this_arg = (++argind >= argc ? 0 : argv[argind]);
  1238.                 else           this_arg = tcp;
  1239.                 if (!this_arg || sscanf(this_arg,"%hd", &pagesize) != 1)
  1240.                    Fatal("Argument of -s is not a valid integer\n");
  1241.                 switch (pagesize) {
  1242.                 case 1: pgsiz_dots = 3150; break;         /* executive */
  1243.                 case 2: pgsiz_dots = 3300; break;         /* letter */
  1244.                 case 3: pgsiz_dots = 4200; break;         /* legal */
  1245.                 case 26: pgsiz_dots = 3507; break;        /* a4 */
  1246.                 case 80: pgsiz_dots = 2250; break;        /* monarc */
  1247.                 case 81: pgsiz_dots = 2850; break;        /* com10 */
  1248.                 case 90: pgsiz_dots = 2598; break;        /* int dl */
  1249.                 case 91: pgsiz_dots = 2704; break;        /* int c5 */
  1250.                 default: Fatal(
  1251.                    "%hd is a bad value for pagesize (1,2,3,26,80,81,90,91)",
  1252.                    pagesize);
  1253.                 }
  1254.                 break;
  1255. #endif
  1256.             case 't':       /* ending pagenumber */
  1257.                 if ( sscanf(tcp + 1, "%ld", &LastPage) != 1 )
  1258.                     Fatal("Argument is not a valid integer\n");
  1259.                 break;
  1260.             case 'v':    /* verbatim mode (print pxl-file names) */
  1261.                 G_noverbatim = FALSE;
  1262.                 break;
  1263.             case 'w':       /* don't print out warnings */
  1264.                 G_nowarn = TRUE;
  1265.                 break;
  1266. #ifdef LJ
  1267.             case 'z':
  1268.                 PrintTestPage = (bool)(!PrintTestPage);
  1269.                 break;
  1270. #endif
  1271.             default:
  1272.                 fprintf(stderr, "%c is not a legal flag\n", *tcp);
  1273.             }
  1274.         } else {
  1275.  
  1276.             (void) strcpy(filename, tcp);
  1277.             tcp = strrchr(argv[argind], '/');
  1278.             /* split into directory + file name */
  1279.             if (tcp == NULL)  {
  1280.                 curarea[0] = '\0';
  1281.                 tcp = argv[argind];
  1282.             } else {
  1283.                 (void) strcpy(curarea, argv[argind]);
  1284.                 curarea[tcp-argv[argind]+1] = '\0';
  1285.                 tcp += 1;
  1286.             }
  1287.  
  1288.             (void) strcpy(curname, tcp);
  1289.             /* split into file name + extension */
  1290.             tcp1 = strchr(tcp, '.');
  1291.             if (tcp1 == NULL) {
  1292.                 (void) strcpy(rootname, curname);
  1293.                 strcat(curname, ".dvi");
  1294.             } else {
  1295.                 *tcp1 = '\0';
  1296.                 (void) strcpy(rootname, curname);
  1297.                 *tcp1 = '.';
  1298.             }
  1299.  
  1300.             (void) strcpy(filename, curarea);
  1301.             (void) strcat(filename, curname);
  1302.  
  1303.             if ((dvifp = BINOPEN(filename)) == NULL)  {
  1304.                 Fatal("%s: can't find DVI file \"%s\"\n\n",
  1305.                        G_progname, filename);
  1306.             }
  1307.         }
  1308.         argind++;
  1309.     }
  1310.  
  1311.     x_goffset = (short) MM_TO_PXL(x_offset) + x_origin;
  1312.     y_goffset = (short) MM_TO_PXL(y_offset) + y_origin;
  1313.  
  1314.     if (dvifp == NULL)  {
  1315.       fprintf(stderr,"\nThis is the DVI to %s converter version %s",
  1316.           PRINTER, VERSION);
  1317.       fprintf(stderr," (%s)\n", OS);
  1318.       fprintf(stderr,"usage: %s [OPTIONS] dvifile\n", G_progname);
  1319.  
  1320.       fprintf(stderr,"OPTIONS are:\n");
  1321.       fprintf(stderr,
  1322.         "\t-aX ..... X= searchpath leading to pixel-files (.pk or .pxl)\n");
  1323. #ifdef IBM3812
  1324.       fprintf(stderr,
  1325.         "\t-b  ..... take paper for first page from alternate casette\n");
  1326. #endif
  1327.       fprintf(stderr,"\t-cX ..... X= number of copies\n");
  1328. #ifdef DEBUG
  1329.       fprintf(stderr,"\t-d  ..... turns debug output on\n");
  1330. #endif
  1331.       fprintf(stderr,"\t-D  ..... turns doublepage output on\n");
  1332.       fprintf(stderr,"\t-eX ..... X= output file\n");
  1333.       fprintf(stderr,"\t-fX ..... print from begin of page number X\n");
  1334. #ifdef LJ
  1335.       fprintf(stderr,
  1336.           "\t-g  ..... do not reset printer at begin of job (go)\n");
  1337. #endif
  1338.       fprintf(stderr,"\t-hX ..... X= name of headerfile\n");
  1339. #ifdef LJ2P
  1340.       fprintf(stderr,"\t-l  ..... landscape mode\n");
  1341. #endif
  1342.       fprintf(stderr,"\t-mX ..... magnification X=0;h;1;2;3;4;5;#xxxx\n");
  1343.       fprintf(stderr,"\t-pX ..... print X pages\n");
  1344.       fprintf(stderr,"\t-q  ..... quiet operation\n");
  1345.       fprintf(stderr,"\t-r  ..... process pages in reverse order\n");
  1346. #ifdef LJ
  1347.       fprintf(stderr,"\t-sX ..... set paper size to X (see documentation)\n");
  1348. #endif
  1349.       fprintf(stderr,"\t-tX ..... print to end of page number X\n");
  1350.       fprintf(stderr,"\t-w  ..... don't print out warnings\n");
  1351.       fprintf(stderr,"\t-v  ..... tell user which pixel-files are used\n");
  1352.       fprintf(stderr,"\t-xX ..... X= x-offset on printout in mm\n");
  1353.       fprintf(stderr,"\t-yX ..... X= y-offset on printout in mm\n");
  1354.       fprintf(stderr,"\t-XO ..... O= x page origin in dots (default=%d)\n",
  1355.             XDEFAULTOFF );
  1356.       fprintf(stderr,"\t-YO ..... O= y page origin in dots (default=%d)\n",
  1357.             YDEFAULTOFF );
  1358. #ifdef LJ
  1359.       fprintf(stderr,
  1360.           "\t-z  ..... print test page with pagecounter after job\n");
  1361. #endif
  1362.       exit(1);
  1363.     }
  1364.     if (EQ(EmitFileName, "")) {
  1365.         if ((EmitFileName = (char *)malloc( STRSIZE )) != (void *)NULL)
  1366.             allocated_storage += STRSIZE;
  1367.         else
  1368.             Fatal("Can't allocate storage of %d bytes\n",STRSIZE);
  1369.         (void) strcpy(EmitFileName, curname);
  1370.         tcp1 = strchr(EmitFileName, '.');
  1371.         *tcp1 = '\0';
  1372.         strcat(EmitFileName, EMITFILE_EXTENSION);
  1373.     }
  1374. }
  1375.  
  1376.  
  1377. /*-->DoConv*/
  1378. /*********************************************************************/
  1379. /********************************  DoConv  ***************************/
  1380. /*********************************************************************/
  1381. long
  1382. DoConv(num, den, convResolution)
  1383. long    num, den;
  1384. int     convResolution;
  1385. {
  1386.     /*register*/ double conv;
  1387.     double foo, bar, blat;
  1388.  
  1389.     foo  = ((double)num / (double)den);
  1390.     bar  = ((double)mag / 1000.0);
  1391.     blat = ((double)convResolution/254000.0);
  1392.     conv = foo * bar * blat;
  1393.  
  1394. /*** too complex an expression for compiler
  1395.     conv = ((double)num / (double)den) *
  1396.             ((double)mag / 1000.0) *
  1397.           ((double)convResolution/254000.0);
  1398. ***/
  1399.  
  1400.     return((long) ((1.0/conv)+0.5));
  1401. }
  1402.  
  1403.  
  1404. /*-->DoSpecial*/
  1405. /*********************************************************************/
  1406. /*****************************  DoSpecial  ***************************/
  1407. /*********************************************************************/
  1408. typedef enum  {
  1409.     None, String, Integer, Number, Dimension}
  1410.  
  1411.  
  1412. ValTyp;
  1413. typedef struct {
  1414.     char    *Key;       /* the keyword string */
  1415.     char    *Val;       /* the value string */
  1416.     ValTyp  vt;         /* the value type */
  1417.     union {         /* the decoded value */
  1418.         int     i;
  1419.         float   n;
  1420.     } v;
  1421. } KeyWord;
  1422. typedef struct {
  1423.     char    *Entry;
  1424.     ValTyp  Typ;
  1425. } KeyDesc;
  1426. #define PSFILE 0
  1427. #define ORIENTATION 1
  1428. #define RESETPOINTS 2
  1429. #define DEFPOINT 3
  1430. #define FILL 4
  1431. #define GRAY 5
  1432. #define PATTERN 6
  1433. KeyDesc KeyTab[] = {
  1434.     { "file", String },
  1435.     { "orientation", Integer},
  1436.     { "resetpoints", String},
  1437.     { "defpoint", String},
  1438.     { "fill", String},
  1439.     { "gray", Integer},
  1440.     { "pattern", Integer}
  1441.    /*,
  1442.              {"hsize", Dimension},
  1443.              {"vsize", Dimension},
  1444.              {"hoffset", Dimension},
  1445.              {"voffset", Dimension},
  1446.              {"hscale", Number},
  1447.              {"vscale", Number}*/
  1448.  
  1449.  
  1450. };
  1451.  
  1452.  
  1453. #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
  1454. void
  1455. DoSpecial( str, n )
  1456. /* interpret a \special command, made up of keyword=value pairs */
  1457. char    *str;
  1458. int     n;
  1459. {
  1460. char    spbuf[STRSIZE], xs[STRSIZE], ys[STRSIZE];
  1461. char    *sf = NULL;
  1462. float   x,y;
  1463. long     x_pos, y_pos;
  1464. KeyWord k;
  1465. int     i, j, j1;
  1466. static int GrayScale=10, Pattern=1;
  1467. static bool    GrayFill=TRUE;
  1468. static long    p_x[80], p_y[80];
  1469. str[n] = '\0';
  1470. spbuf[0] = '\0';
  1471.  
  1472. SetPosn(h, v);
  1473. while ( (str = GetKeyStr(str, &k)) != NULL ) {
  1474.     /* get all keyword-value pairs */
  1475.     /* for compatibility, single words are taken as file names */
  1476.     if ( k.vt == None && access(k.Key, 0) == 0) {
  1477.         if ( sf )
  1478.             Warning("More than one \\special file name given. %s ignored", sf);
  1479.         (void) strcpy(spbuf, k.Key);
  1480.         sf = spbuf;
  1481. /*
  1482.         for (j = 1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++);
  1483. */
  1484.     } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i != -1 )
  1485.         switch (i) {
  1486.         case PSFILE:
  1487.             if ( sf )
  1488.                 Warning("More than one \\special file name given. %s ignored",
  1489.                             sf);
  1490.             (void) strcpy(spbuf, k.Val);
  1491.             sf = spbuf;
  1492. /*
  1493.             for (j=1; ((sf[j]=='/' ? sf[j]='\\':sf[j]) != '\0'); j++) ;
  1494. */
  1495.             break;
  1496.         case ORIENTATION:
  1497. #ifdef IBM3812
  1498.             if ((k.v.i >= 0) && (k.v.i < 4)) {
  1499.                 last_ry = UNKNOWN;
  1500.                 sprintf(PMPformat, "\322%c", (unsigned char)k.v.i);
  1501.                 PMPout(2, PMPformat);
  1502.         if (k.v.i == 1) Landscape = TRUE;
  1503.         else if (k.v.i == 0) Landscape = FALSE;
  1504. #endif
  1505. #ifdef LJ
  1506.             if ((k.v.i >= 0) && (k.v.i < 2)) {
  1507.                 last_ry = UNKNOWN;
  1508.                 EMIT(outfp, "\033&l%dO\033*rF", (unsigned char)k.v.i);
  1509. #endif
  1510.             } else
  1511.                 Warning( "Invalid orientation (%d)given; ignored.", k.v.i);
  1512.             break;
  1513.         case RESETPOINTS:
  1514.             (void) strcpy(spbuf, k.Val);
  1515.  
  1516.             sf = NULL;
  1517.             break;
  1518.  
  1519.         case DEFPOINT:
  1520.           (void) strcpy(spbuf, k.Val);
  1521.            i=sscanf(spbuf,"%d(%[^,],%s)",&j,xs,ys);
  1522.            if (i>0) {
  1523.               x_pos=h; y_pos=v;
  1524.               if (i>1) {
  1525.                   if (sscanf(xs,"%fpt",&x)>0) {
  1526.                      fprintf(stderr,"x = %f\n",x);
  1527.                      x_pos = PT_TO_DVI(x);
  1528.              }
  1529.               }
  1530.               if (i>2) {
  1531.                   if (sscanf(ys,"%fpt",&y)>0) {
  1532.                      fprintf(stderr,"y = %f\n",y);
  1533.                      y_pos = PT_TO_DVI(y);
  1534.                 }
  1535.               }
  1536.               p_x[j]=x_pos;
  1537.               p_y[j]=y_pos;
  1538.            } else
  1539.              Warning("invalid point definition\n");
  1540.  
  1541.            sf = NULL;
  1542.            break;
  1543.  
  1544.         case FILL:
  1545.           (void) strcpy(spbuf, k.Val);
  1546.            i=sscanf(spbuf,"%d/%d %s",&j,&j1,xs);
  1547.            if (i>1) {
  1548. #ifdef LJ
  1549.               SetPosn(p_x[j], p_y[j]);
  1550.               x_pos = (long)PIXROUND(p_x[j1]-p_x[j], hconv);
  1551.               y_pos = (long)PIXROUND(p_y[j1]-p_y[j], vconv);
  1552.               if (labs(x_pos)<labs(y_pos)) x_pos=x_pos+3;
  1553.               else                         y_pos=y_pos+3;
  1554.               if (GrayFill) {
  1555.                   EMIT(outfp, "\033*c%lda%ldb%dg2P", x_pos, y_pos, GrayScale);
  1556.               } else {
  1557.                   EMIT(outfp, "\033*c%lda%ldb%dg3P", x_pos, y_pos, Pattern);
  1558.               }
  1559.               last_ry = UNKNOWN;
  1560. #endif
  1561.            }
  1562.            break;
  1563.         case GRAY:
  1564.             if ((k.v.i >= 0) && (k.v.i < 101)) {
  1565.                 GrayScale = k.v.i;
  1566.                 GrayFill = TRUE;
  1567.             } else
  1568.                 Warning( "Invalid gray scale (%d) given; ignored.", k.v.i);
  1569.             break;
  1570.         case PATTERN:
  1571.             if ((k.v.i >= 0) && (k.v.i < 7)) {
  1572.                 Pattern = k.v.i;
  1573.                 GrayFill = FALSE;
  1574.             } else
  1575.                 Warning( "Invalid pattern (%d) given; ignored.", k.v.i);
  1576.             break;
  1577.  
  1578.         default:
  1579.             Warning("Can't handle %s=%s command; ignored.", k.Key, k.Val);
  1580.             break;
  1581.         }
  1582.     else
  1583.         Warning("Invalid keyword or value in \\special - <%s> ignored", k.Key);
  1584. }
  1585. if ( sf ) {
  1586.     last_ry = UNKNOWN;
  1587. #ifdef IBM3812
  1588.     PMPflush;
  1589. #endif
  1590.     CopyFile( sf );
  1591.    }
  1592. }
  1593.  
  1594.  
  1595. /*-->EmitChar*/
  1596. /**********************************************************************/
  1597. /****************************  EmitChar  ******************************/
  1598. /**********************************************************************/
  1599. void                     /* output a character bitmap */
  1600. EmitChar(c, ce)
  1601. long    c;
  1602. struct char_entry *ce;
  1603. {
  1604.     register int    i;
  1605.     register unsigned char  *sl;
  1606.     unsigned short  nbpl, nwpl;
  1607.     long    total;
  1608. #ifdef LJ
  1609.     unsigned char cnv_buffer[10];
  1610. #endif
  1611.  
  1612. /*
  1613. #ifdef LJ
  1614. printf("Emit character %c(%d) id=%d, yoff=%d[%d], w=%d[%d], h=%d[%d]\n",
  1615.         (char)c,(int)c,
  1616.     fontptr->plusid,
  1617.     ce->yOffset, fontptr->max_yoff,
  1618.     ce->width,   fontptr->max_width,
  1619.     ce->height,  fontptr->max_height
  1620. );
  1621. #endif
  1622. */
  1623.  
  1624.     if ( fontptr->ncdl == 0 ) {
  1625. #ifdef IBM3812
  1626.         used_fontstorage += 1028;
  1627. #endif
  1628. #ifdef LJ
  1629.         if (fontptr->max_width == 0) { /* we have no realistic values */
  1630.                 fontptr->max_yoff = CHAR_HEIGTH_LARGE;
  1631.                 fontptr->max_width = CHAR_WIDTH_LARGE;
  1632.                 fontptr->max_height = CHAR_HEIGTH_LARGE*2;
  1633.         }
  1634.  
  1635.         /* open font dict before first char, set active font */
  1636.         INT_ASCII(cnv_buffer,fontptr->plusid);
  1637.         EMIT(outfp, "\033*c%sD\033)s26W", cnv_buffer);
  1638. /*      EMITB(20, "\0\032\0\1\0\0\0\310\0\377\0\377\0\1\1\025\0\4\0\4");*/
  1639.  
  1640.         EMITB(6, "\0\032\0\2\0\0");        /* GUGUGU 255 */
  1641.         EMITWORD( fontptr->max_yoff);
  1642.         EMITWORD( fontptr->max_width);
  1643.         EMITWORD( fontptr->max_height);
  1644. /*        EMITC((char)(Landscape==TRUE));  */
  1645.         EMITC((char)0);
  1646.         EMITB(7, "\1\1\25\0\4\0\4");
  1647.         EMITB(6, "\0\0\0\0\0\0");
  1648.         EMIT(outfp, "\033*c4F");
  1649. #endif
  1650.     }
  1651.     if ( fontptr != prevfont ) {   /* because this isn't done on pass 0 */
  1652. #ifdef LJ
  1653.         INT_ASCII(cnv_buffer,fontptr->plusid);
  1654.         EMIT(outfp, "\033(%sX", cnv_buffer);
  1655. #endif
  1656.         prevfont = fontptr;
  1657.     }
  1658.  
  1659. #ifdef USEPXL
  1660.     if (fontptr->id == pk89)   {
  1661.         nbpl = ((ce->width) +  7) >> 3;
  1662.         total = (long)ce->height * nbpl;
  1663.     } else if (fontptr->id == id1002)   {
  1664.         nbpl = ((ce->width) +  7) >> 3;
  1665.         total = (long)ce->height * nbpl;
  1666.     } else if (fontptr->id == id1001) {
  1667.         nwpl = ((ce->width) + 31) >> 5;
  1668.         nbpl = ((ce->width) + 7) >> 3;
  1669.         total = (long)ce->height * nbpl;
  1670.     }
  1671. #else
  1672.     nbpl = (num_cols + 7) >> 3;
  1673.     total = num_rows * nbpl;
  1674. #endif
  1675. /***************************************************************
  1676.     if ( ((char) c == 'i') && (fontptr->plusid == 0)) {
  1677.         long j;
  1678.         printf("cols=%ld, ncols=%ld\n",nwpl,nbpl);
  1679.  
  1680.         printf("%ld Bytes:->",total);
  1681.         for (j=0; j<total;j++) {
  1682.             char *ch; char ic;
  1683.             ch = (char *)(ce->where.address.pixptr);
  1684.             ic = *(ch+j);
  1685.             printf("%X.",ic);
  1686.                 }
  1687.         printf("<- Now Emitting\n");
  1688.         }
  1689. ***************************************************************/
  1690. #ifdef USEPXL
  1691. #ifdef IBM3812
  1692.     if ((short)(ce->height) - ce->yOffset > 55) {
  1693.         ce->yyOffset = (short) ce->height - ce->yOffset;
  1694.         ce->yOffset  = (short) ce->height;
  1695.     } else {
  1696.         ce->yyOffset = (short) 0;
  1697.     }
  1698. #endif
  1699. #ifdef LJ
  1700.         ce->yyOffset = (short) 0;
  1701. #endif
  1702. #endif
  1703.  
  1704.     /* ce->cw = (long)(((double)ce->tfmw / (double)hconv) +0.5); */
  1705.     /* set active font to nn, load font pattern  xx ... */
  1706. #ifdef IBM3812
  1707.     PMPcont(total + 9);
  1708. #ifdef USEPXL
  1709.     sprintf(PMPformat, "\323%c\360%c%c%c",
  1710.         (unsigned char)fontptr->plusid,
  1711.         (unsigned char)c,
  1712.         (unsigned char)ce->height,
  1713.         (unsigned char)ce->width);
  1714.     PMPout(6, PMPformat);
  1715.     PMPoutC((char)(-(ce->xOffset)));
  1716.     PMPoutC((char)(ce->cw - (-ce->xOffset + ce->width)));
  1717.     PMPoutC((char)(ce->yOffset));
  1718. #else
  1719.     sprintf(PMPformat, "\323%c\360%c%c%c",
  1720.         (unsigned char)fontptr->plusid,
  1721.         (unsigned char)c,
  1722.         (unsigned char)num_rows,
  1723.         (unsigned char)num_cols);
  1724.     PMPout(6, PMPformat);
  1725.     PMPoutC((char)(-x_offset));
  1726.     PMPoutC((char)(ce->cw - (-x_offset + num_cols)));
  1727.     PMPoutC((char)num_rows-y_offset);
  1728. #endif
  1729. #endif
  1730. #ifdef LJ
  1731.     INT_ASCII(cnv_buffer,fontptr->plusid);
  1732.     EMIT(outfp, "\033*c%sd%dE\033(s%ldW", cnv_buffer,
  1733.         (unsigned int)c, (long)(total + 16));
  1734.     EMITB(4, "\4\0\016\1");
  1735. /*    EMITC((char)(Landscape==TRUE)); */
  1736.     EMITC((char)0);
  1737.     EMITC((char)0);
  1738. #ifdef USEPXL
  1739.     EMITWORD(-ce->xOffset);
  1740.     EMITWORD(ce->yOffset);
  1741.     EMITWORD(ce->width);
  1742.     EMITWORD(ce->height);
  1743. #else
  1744.     EMITWORD(-x_offset);
  1745.     EMITWORD(num_rows-y_offset);
  1746.     EMITWORD(num_cols);
  1747.     EMITWORD(num_rows);
  1748. #endif
  1749.     EMITWORD((int)ce->cw * 4);
  1750. #endif
  1751. #ifdef USEPXL
  1752.  
  1753.     if (fontptr->id == pk89)
  1754.         PkRaster(ce, FALSE);
  1755.     else if (fontptr->id == id1002)
  1756.         for (i = 0; i < (int) ce->height; i++) {
  1757.             sl = ((unsigned char *)(ce->where.address.pixptr) + i * nbpl);
  1758.             EMITL(nbpl, sl);
  1759.         }
  1760.     else if (fontptr->id == id1001)
  1761.         for (i = 0; i < (int) ce->height; i++) {
  1762.             sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
  1763.             EMITL(nbpl, sl);
  1764.         }
  1765. #else
  1766.     for (i = num_rows; i > 0; i--)
  1767.       {
  1768.         EMITL (nbpl, bits + (i-1) * nbpl);
  1769.       }
  1770. #endif
  1771. #ifdef IBM3812
  1772. #ifdef USEPXL
  1773.     used_fontstorage += (long)ce->height * ((ce->width + 15) >> 4)
  1774.         *2 + 14;
  1775. #else
  1776.     used_fontstorage += (long)num_rows * ((num_cols + 15) >> 4)
  1777.         *2 + 14;
  1778. #endif
  1779. #endif
  1780. #ifdef LJ
  1781. #ifdef USEPXL
  1782.     used_fontstorage += 64 * ((((ce->height * ce->width) - 1) / 64) + 1);
  1783. #else
  1784.     used_fontstorage += 64 * ((((num_rows * num_cols) - 1) / 64) + 1);
  1785. #endif
  1786. #endif
  1787.     fontptr->ncdl += 1;
  1788.     G_ncdl += 1;
  1789. }
  1790.  
  1791.  
  1792. /*-->RasterLine*/
  1793. /**********************************************************************/
  1794. /****************************  RasterLine  ****************************/
  1795. /**********************************************************************/
  1796. void
  1797. RasterLine(ce, nbpl, current_line, buffer)
  1798. struct char_entry *ce;
  1799. unsigned short  nbpl, current_line;
  1800. char    *buffer;
  1801. {
  1802. #ifdef IBM3812
  1803.     long    total;
  1804.     static unsigned short   maxlines;
  1805.  
  1806.     if (current_line == 0) {
  1807. #ifdef USEPXL
  1808.         maxlines = ce->height;
  1809.  
  1810.         MoveVert(-ce->yOffset);      /* move cursor up */
  1811.         MoveHor(-ce->xOffset);       /* move cursor right */
  1812. #else
  1813.         maxlines = num_rows;
  1814.  
  1815.         MoveVert(-(num_rows-y_offset));      /* move cursor up */
  1816.         MoveHor(-x_offset);       /* move cursor right */
  1817. #endif
  1818.         last_ry = UNKNOWN;       /* next time full positioning */
  1819.     }
  1820.  
  1821.     if (current_line % maxlines == 0) {
  1822.         if (current_line > 0) {    /* maxlines lines have been printed*/
  1823.             MoveVert(maxlines);   /*   move cursor down     */
  1824.             last_ry = UNKNOWN;    /* next time full positioning */
  1825.         }
  1826. #ifdef USEPXL
  1827.         total = (long)(ce->height - current_line) * (long)nbpl;
  1828. #else
  1829.         total = (long)(num_rows - current_line) * (long)nbpl;
  1830. #endif
  1831.         if ((total + 9) > 65535) {
  1832.             maxlines = (unsigned short)((65535 - 9) / nbpl);
  1833.             total = (long)maxlines * (long)nbpl;
  1834.         }
  1835.  
  1836.         PMPcont(total + 9);
  1837.         PMPout(2, "\365\0");
  1838.         EMITWORD(maxlines);
  1839. #ifdef USEPXL
  1840.         EMITWORD(ce->width);
  1841. #else
  1842.         EMITWORD(num_cols);
  1843. #endif
  1844.         PMPoutC((unsigned char) (total >> 16) & 0xFF);
  1845.         PMPoutC((unsigned char) (total >> 8 ) & 0xFF);
  1846.         PMPoutC((unsigned char)  total     & 0xFF);
  1847.     }
  1848.     EMITL((int)nbpl, buffer);
  1849. #endif
  1850. #ifdef LJ
  1851.     register int    emitbytes;
  1852.  
  1853.     for (emitbytes = (int)nbpl;
  1854.         (*(buffer + emitbytes - 1) == '\0') && (emitbytes > 0);
  1855.         emitbytes--) ;
  1856.     EMIT(outfp, "\033*b%dW", emitbytes);
  1857.     EMITL(emitbytes, buffer);
  1858. #endif
  1859. }
  1860.  
  1861.  
  1862. /*-->RasterChar*/
  1863. /**********************************************************************/
  1864. /****************************  RasterChar  ****************************/
  1865. /**********************************************************************/
  1866. void                     /* raster a character bitmap */
  1867. RasterChar(ce)
  1868. struct char_entry *ce;
  1869. {
  1870.     int     i;
  1871.     register unsigned char  *sl;
  1872.     unsigned short  nbpl, nwpl;
  1873.     unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
  1874.  
  1875. #ifdef DEBUG
  1876.     if (Debug)
  1877.         fprintf(stderr,"Raster character ...size=%d \n", (int)ce->charsize );
  1878. #endif
  1879.  
  1880. #ifdef USEPXL
  1881.     if (fontptr->id == pk89)   {
  1882.         nbpl = ((ce->width) +  7) >> 3;
  1883.     } else if (fontptr->id == id1002)   {
  1884.         nbpl = ( ce->width +  7) >> 3;
  1885.     } else if (fontptr->id == id1001) {
  1886.         nwpl = ( ce->width + 31) >> 5;
  1887.         nbpl = ( ce->width + 7) >> 3;
  1888.     }
  1889. #else
  1890.     nbpl = (num_cols + 7) >> 3;
  1891. #endif
  1892.  
  1893. #ifdef LJ
  1894.     EMIT(outfp, "\033*t300R\033*r1A");
  1895. #endif
  1896.  
  1897.                                             { /* read pixel from file */
  1898.     if ((ce->charsize == HUGE_SIZE) && (fontptr->id != pk89))
  1899.         OpenFontFile();
  1900. #ifdef USEPXL
  1901.         fseek(pxlfp, ce->where.address.fileOffset, 0);
  1902. #else
  1903.         fseek(gfin, ce->where.address.fileOffset, 0);
  1904.         gettochar();
  1905.         readbits();
  1906. #endif
  1907.     }
  1908.  
  1909. #ifdef USEPXL
  1910.     if (fontptr->id == pk89)
  1911.         PkRaster(ce, TRUE);
  1912.     else if (fontptr->id == id1002) {
  1913.         for (i = 0; i < (int) ce->height; i++) {
  1914.             if (ce->charsize == HUGE_SIZE) {
  1915.                 fread(raster_line_buf, 1, (int) nbpl, pxlfp);
  1916.                 sl = raster_line_buf;
  1917.             } else
  1918.                 sl = ((unsigned char *)(ce->where.address.pixptr)
  1919.                     + i * nbpl);
  1920.  
  1921.             RasterLine(ce, (unsigned int)nbpl, i, sl);
  1922.         }
  1923.     } else if (fontptr->id == id1001) {
  1924.         long    filediff;
  1925.         filediff = (long)nwpl * 4 - nbpl;
  1926.         for (i = 0; i < (int) ce->height; i++) {
  1927.             if (ce->charsize == HUGE_SIZE) {
  1928.                 fread(raster_line_buf, 1, (int) nbpl, pxlfp);
  1929.                 /* skip fill bytes */
  1930.                 fseek(pxlfp, filediff, 1);
  1931.                 sl = raster_line_buf;
  1932.             } else
  1933.                 sl = (unsigned char *)(ce->where.address.pixptr + i * nwpl);
  1934.  
  1935.             RasterLine(ce, (unsigned int)nbpl, i, sl);
  1936.         }
  1937.     }
  1938. #else
  1939.     for (i = num_rows; i > 0; i--)
  1940.       RasterLine(ce, (unsigned int)nbpl, i, bits + (i-1) * nbpl);
  1941. #endif
  1942. #ifdef LJ
  1943.     EMIT(outfp, "\033*rB");
  1944. #endif
  1945.     last_ry = UNKNOWN;
  1946. }
  1947.  
  1948.  
  1949. /*-->Fatal*/
  1950. /**********************************************************************/
  1951. /******************************  Fatal  *******************************/
  1952. /**********************************************************************/
  1953. void
  1954. Fatal(fmt, a, b, c)      /* issue a fatal error message */
  1955. char    *fmt;           /* format              */
  1956. char    *a, *b, *c;     /* arguments           */
  1957. {
  1958.     fprintf(stderr, "\n");
  1959.     fprintf(stderr, "%s: FATAL--", G_progname);
  1960.     fprintf(stderr, fmt, a, b, c);
  1961.     fprintf(stderr, "\n\n");
  1962.     exit(2);
  1963. }
  1964.  
  1965.  
  1966. /*-->FindPostAmblePtr*/
  1967. /**********************************************************************/
  1968. /************************  FindPostAmblePtr  **************************/
  1969. /**********************************************************************/
  1970. void
  1971. FindPostAmblePtr(postambleptr)
  1972. long    *postambleptr;
  1973. /* this routine will move to the end of the file and find the start
  1974.     of the postamble */
  1975. {
  1976.     long    i;
  1977.     fseek (dvifp,  0l, 2);   /* goto end of file */
  1978.     *postambleptr = ftell (dvifp) - 4;
  1979.     fseek (dvifp, *postambleptr, 0);
  1980.     while (TRUE) {
  1981.         fseek (dvifp, --(*postambleptr), 0);
  1982.         if (((i = NoSignExtend(dvifp, 1)) != 223) &&
  1983.             (i != DVIFORMAT))
  1984.             Fatal ("Bad end of DVI file");
  1985.         if (i == DVIFORMAT)
  1986.             break;
  1987.     }
  1988.     fseek (dvifp, (*postambleptr) - 4, 0);
  1989.     (*postambleptr) = NoSignExtend(dvifp, 4);
  1990.     fseek (dvifp, *postambleptr, 0);
  1991. }
  1992.  
  1993.  
  1994. /*-->GetBytes*/
  1995. /**********************************************************************/
  1996. /*****************************  GetBytes  *****************************/
  1997. /**********************************************************************/
  1998. void
  1999. GetBytes(fp, cp, n)     /* get n bytes from file fp */
  2000. /*register*/ FILE *fp;      /* file pointer  */
  2001. register char   *cp;    /* character pointer */
  2002. int     n;            /* number of bytes  */
  2003. {
  2004.     while (n--)
  2005.         *cp++ = (char)getc(fp);
  2006. }
  2007.  
  2008.  
  2009. /*-->GetFontDef*/
  2010. /**********************************************************************/
  2011. /**************************** GetFontDef  *****************************/
  2012. /**********************************************************************/
  2013. void
  2014. GetFontDef()
  2015. /***********************************************************************
  2016.    Read the font  definitions as they  are in the  postamble of the  DVI
  2017.    file.
  2018. ***********************************************************************/
  2019. {
  2020.     unsigned char   byte;
  2021.     while (((byte = (unsigned char) NoSignExtend(dvifp, 1)) >= FNT_DEF1) &&
  2022.         (byte <= FNT_DEF4)) {
  2023.         switch (byte) {
  2024.         case FNT_DEF1:
  2025.             ReadFontDef ( NoSignExtend(dvifp, 1));
  2026.             break;
  2027.         case FNT_DEF2:
  2028.             ReadFontDef ( NoSignExtend(dvifp, 2));
  2029.             break;
  2030.         case FNT_DEF3:
  2031.             ReadFontDef ( NoSignExtend(dvifp, 3));
  2032.             break;
  2033.         case FNT_DEF4:
  2034.             ReadFontDef ( NoSignExtend(dvifp, 4));
  2035.             break;
  2036.         default:
  2037.             Fatal ("Bad byte value in font defs");
  2038.             break;
  2039.         }
  2040.     }
  2041.     if (byte != POST_POST)
  2042.         Fatal ("POST_POST missing after fontdefs");
  2043. }
  2044.  
  2045.  
  2046. /*-->GetKeyStr*/
  2047. /**********************************************************************/
  2048. /*****************************  GetKeyStr  ****************************/
  2049. /**********************************************************************/
  2050. /* extract first keyword-value pair from string (value part may be null)
  2051.  * return pointer to remainder of string
  2052.  * return NULL if none found
  2053.  */
  2054. char    KeyStr[STRSIZE];
  2055. char    ValStr[STRSIZE];
  2056. char
  2057. *GetKeyStr( str, kw )
  2058. char    *str;
  2059. KeyWord *kw;
  2060. {
  2061.     char    *s, *k, *v, t;
  2062.     if ( !str )
  2063.         return( NULL );
  2064.     for ( s = str; *s == ' '; s++)
  2065.         ;          /* skip over blanks */
  2066.     if ( *s == '\0' )
  2067.         return( NULL );
  2068.     for ( k = KeyStr; /* extract keyword portion */
  2069.     *s != ' ' && *s != '\0' && *s != '=';
  2070.         *k++ = *s++)
  2071.         ;
  2072.     *k = '\0';
  2073.     kw->Key = KeyStr;
  2074.     kw->Val = v = NULL;
  2075.     kw->vt = None;
  2076.     for ( ; *s == ' '; s++)
  2077.         ;            /* skip over blanks */
  2078.     if ( *s != '=' )         /* look for "=" */
  2079.         return( s );
  2080.     for ( s++; *s == ' '; s++);      /* skip over blanks */
  2081.     if ( *s == '\'' || *s == '\"' )  /* get string delimiter */
  2082.         t = *s++;
  2083.     else
  2084.         t = ' ';
  2085.     for ( v = ValStr; /* copy value portion up to delim */
  2086.     *s != t && *s != '\0';
  2087.         *v++ = *s++)
  2088.         ;
  2089.     if ( t != ' ' && *s == t )
  2090.         s++;
  2091.     *v = '\0';
  2092.     kw->Val = ValStr;
  2093.     kw->vt = String;
  2094.     return( s );
  2095. }
  2096.  
  2097.  
  2098. /*-->GetKeyVal*/
  2099. /**********************************************************************/
  2100. /*****************************  GetKeyVal  ****************************/
  2101. /**********************************************************************/
  2102. /* get next keyword-value pair decode value according to table entry  */
  2103. bool
  2104. GetKeyVal( kw, tab, nt, tno)
  2105. KeyWord *kw;
  2106. KeyDesc tab[];
  2107. int     nt;
  2108. int     *tno;
  2109. {
  2110.     int     i;
  2111.     char    c = '\0';
  2112.     *tno = -1;
  2113.     for (i = 0; i < nt; i++)
  2114.         if ( IsSame(kw->Key, tab[i].Entry) ) {
  2115.             *tno = i;
  2116.             switch ( tab[i].Typ ) {
  2117.             case None:
  2118.                 if ( kw->vt != None )
  2119.                     return( FALSE );
  2120.                 break;
  2121.             case String:
  2122.                 if ( kw->vt != String )
  2123.                     return( FALSE );
  2124.                 break;
  2125.             case Integer:
  2126.                 if ( kw->vt != String )
  2127.                     return( FALSE );
  2128.                 if ( sscanf(kw->Val, "%d%c",
  2129.                     &(kw->v.i), &c) != 1
  2130.                      || c != '\0' )
  2131.                     return( FALSE );
  2132.                 break;
  2133. /*              case Number:
  2134.  *              case Dimension:
  2135.  *                  if( kw->vt != String ) return( FALSE );
  2136.  *                  if( sscanf(kw->Val,"%f%c",
  2137.  *                     &(kw->v.n), &c) != 1
  2138.  *                  || c != '\0' ) return( FALSE );
  2139.  *                  break;
  2140.  */
  2141.             }
  2142.             kw->vt = tab[i].Typ;
  2143.             return( TRUE );
  2144.         }
  2145.     return( TRUE );
  2146. }
  2147.  
  2148.  
  2149.  
  2150. /*-->IsSame*/
  2151. /**********************************************************************/
  2152. /*******************************  IsSame  *****************************/
  2153. /**********************************************************************/
  2154. bool                  /* compare strings, ignore case */
  2155. IsSame(a, b)
  2156. char    *a, *b;
  2157. {
  2158.     char    *x, *y;
  2159.     x = a;
  2160.     y = b;
  2161.     for ( ; *a != '\0'; )
  2162.         if ( tolower(*a++) != tolower(*b++) )
  2163.             return( FALSE );
  2164.     return( *x == *y ? TRUE : FALSE );
  2165. }
  2166.  
  2167.  
  2168. /*-->NoSignExtend*/
  2169. /**********************************************************************/
  2170. /***************************  NoSignExtend  ***************************/
  2171. /**********************************************************************/
  2172. long
  2173. NoSignExtend(fp, n)     /* return n byte quantity from file fd */
  2174. register FILE *fp;      /* file pointer    */
  2175. register int    n;      /* number of bytes */
  2176. {
  2177.     long    x;      /* number being constructed */
  2178.     x = 0;
  2179.     while (n--)  {
  2180.         x <<= 8;
  2181.         x |= getc(fp);
  2182.     }
  2183.     return(x);
  2184. }
  2185.  
  2186.  
  2187. /*-->OpenFontFile*/
  2188. /**********************************************************************/
  2189. /************************** OpenFontFile  *****************************/
  2190. /**********************************************************************/
  2191. void
  2192. OpenFontFile()
  2193. /***********************************************************************
  2194.     The original version of this dvi driver reopened the font file  each
  2195.     time the font changed, resulting in an enormous number of relatively
  2196.     expensive file  openings.   This version  keeps  a cache  of  up  to
  2197.     MAXOPEN open files,  so that when  a font change  is made, the  file
  2198.     pointer, pxlfp, can  usually be  updated from the  cache.  When  the
  2199.     file is not found in  the cache, it must  be opened.  In this  case,
  2200.     the next empty slot  in the cache  is assigned, or  if the cache  is
  2201.     full, the least used font file is closed and its slot reassigned for
  2202.     the new file.  Identification of the least used file is based on the
  2203.     counts of the number  of times each file  has been "opened" by  this
  2204.     routine.  On return, the file pointer is always repositioned to  the
  2205.     beginning of the file.
  2206. ***********************************************************************/
  2207. {
  2208.     int     i, least_used, current;
  2209.     struct pixel_list tmp;
  2210.  
  2211. #ifdef DEBUG
  2212.     if (Debug)
  2213.         fprintf(stderr,"open font file %d\n", fontptr->font_file_id);
  2214. #endif
  2215. /*
  2216. fprintf(stderr,"? %lx == %lx\n", pfontptr,fontptr);
  2217. */
  2218.     if ((pfontptr == fontptr) && (pxlfp != NO_FILE))
  2219.         return;         /* we need not have been called */
  2220.  
  2221.        if (fontptr->font_file_id == NO_FILE)
  2222.         return;         /* we need not have been called */
  2223.  
  2224.     tmp = pixel_files[1];
  2225.     for (current = 1;
  2226.         (current <= nopen) && (tmp.pixel_file_id != fontptr->font_file_id); ) {
  2227.         ++current;
  2228.         tmp = pixel_files[current];
  2229.     }
  2230.     /* try to find file in open list */
  2231.  
  2232.     if (current <= nopen)       /* file already open */ {
  2233.         if ( (pxlfp = pixel_files[current].pixel_file_id) != NO_FILE )
  2234.             fseek(pxlfp, 0l, 0);
  2235.             /* reposition to start of file */
  2236.     } else {
  2237.             /* file not in open list          */
  2238.         if (nopen < MAXOPEN)    /* just add it to list    */
  2239.             current = ++nopen;
  2240.         else  {
  2241.             /* list full -- find least used file,     */
  2242.             /* close it, and reuse slot for new file  */
  2243.             least_used = 1;
  2244.             for (i = 2; i <= MAXOPEN; ++i)
  2245.                 if (pixel_files[least_used].use_count>pixel_files[i].use_count)
  2246.                     least_used = i;
  2247.             if (pixel_files[least_used].pixel_file_id != NO_FILE) {
  2248.                 FILE * fid;
  2249.                 struct font_entry *fp;
  2250.                 fid = pixel_files[least_used].pixel_file_id;
  2251.                 /* mark file as being closed in the entry */
  2252.                 fp = hfontptr;
  2253.                 while (fp != NULL && fp->font_file_id != fid) fp = fp->next;
  2254.                 if (fp == NULL)
  2255.                    Fatal("Open file %x not found in font entry list.\n", fid);
  2256.                 else {
  2257.                     fp->font_file_id = NULL;
  2258.                 }
  2259.                 fclose( fid );
  2260.             }
  2261. #ifdef DEBUG
  2262.             if (Debug)
  2263.                  fprintf(stderr,"\n__reuse slot %d\n", least_used);
  2264. #endif
  2265.             current = least_used;
  2266.         }
  2267.         if ((pxlfp = BINOPEN(fontptr->name)) == NULL) {
  2268.             Warning("PXL-file %s could not be opened", fontptr->name);
  2269.             pxlfp = NO_FILE;
  2270.         } else {
  2271. #ifdef DEBUG
  2272.              if (Debug) fprintf(stderr,
  2273.              "Opening File  <%s> /%x/, Size(font_entry)=%d\n",
  2274.               fontptr->name, pxlfp, sizeof(struct font_entry ));
  2275. #endif
  2276.  
  2277.         }
  2278.         pixel_files[current].pixel_file_id = pxlfp;
  2279.         pixel_files[current].use_count = 0;
  2280.     }
  2281.     pfontptr = fontptr;         /* make previous = current font */
  2282.     fontptr->font_file_id = pxlfp;      /* set file identifier */
  2283.     pixel_files[current].use_count++;   /* update reference count */
  2284. #ifndef USEPXL
  2285.     gfin = pxlfp;
  2286. #endif
  2287. }
  2288.  
  2289.  
  2290. /*-->PixRound*/
  2291. /**********************************************************************/
  2292. /*****************************  PixRound  *****************************/
  2293. /**********************************************************************/
  2294. long
  2295. PixRound(x, conv)       /* return rounded number of pixels */
  2296. long    x;          /* in DVI units     */
  2297. long    conv;       /* conversion factor */
  2298. {
  2299.     return((x + conv) / conv);
  2300. }
  2301.  
  2302.  
  2303. /*-->ReadFontDef*/
  2304. /**********************************************************************/
  2305. /****************************  ReadFontDef  ***************************/
  2306. /**********************************************************************/
  2307. void
  2308. ReadFontDef(k)
  2309. long    k;
  2310. {
  2311.     long    t;
  2312.     unsigned short i;
  2313.     char    nname[STRSIZE];
  2314.     int nmag;
  2315.     struct font_entry *tfontptr; /* temporary font_entry pointer   */
  2316.     struct char_entry *tcharptr; /* temporary char_entry pointer  */
  2317.     static int      plusid = 0;
  2318.     bool font_found = FALSE;
  2319. #ifdef LJ
  2320.     int depth, max_depth;
  2321. #endif
  2322.  
  2323. #ifdef DEBUG
  2324.     if (Debug)
  2325.         fprintf(stderr,"Mallocating %d Bytes)...\n",
  2326.             sizeof(struct font_entry ));
  2327. #endif
  2328.  
  2329.     if ((tfontptr = NEW(struct font_entry )) == NULL)
  2330.         Fatal("can't malloc space for font_entry");
  2331.  
  2332.     allocated_storage += sizeof(struct font_entry );
  2333.  
  2334.     tfontptr->next = hfontptr;
  2335.     tfontptr->font_file_id = NULL;
  2336.     fontptr = hfontptr = tfontptr;
  2337.     tfontptr->ncdl = 0;
  2338.     tfontptr->k = k;
  2339.     tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */
  2340.     tfontptr->s = NoSignExtend(dvifp, 4); /* space size */
  2341.     tfontptr->d = NoSignExtend(dvifp, 4); /* design size */
  2342.     tfontptr->a = (int) NoSignExtend(dvifp, 1); /* length for font name */
  2343.     tfontptr->l = (int) NoSignExtend(dvifp, 1); /* device length */
  2344.  
  2345. #ifdef LJ
  2346.     tfontptr->max_width = tfontptr->max_height = tfontptr->max_yoff =
  2347.                           max_depth = 0;
  2348. #endif
  2349.  
  2350.     GetBytes(dvifp, tfontptr->n, tfontptr->a + tfontptr->l);
  2351.     tfontptr->n[tfontptr->a+tfontptr->l] = '\0';
  2352.  
  2353.     tfontptr->font_mag = (long)((
  2354.          ActualFactor((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5))
  2355.          * ActualFactor(mag)
  2356. #ifdef USEPXL
  2357.          * RESOLUTION * 5.0
  2358. #else
  2359.          * RESOLUTION
  2360. #endif
  2361.            ) + 0.5);
  2362. /*
  2363. printf("[%ld]=%lf * %lf * %lf + 0.5 = %ld\n",
  2364.     ((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
  2365.     ActualFactor((long)(1000.0*tfontptr->s/(double)tfontptr->d+0.5)),
  2366.     ActualFactor(mag),
  2367.     (double)RESOLUTION * 5,
  2368.     tfontptr->font_mag );
  2369. */
  2370.  
  2371.  
  2372.     if (!(font_found = (bool)
  2373.           findfile(PXLpath, tfontptr->n, tfontptr->font_mag,
  2374.           tfontptr->name))) {
  2375.           Warning(tfontptr->name); /* contains error messsage */
  2376.           tfontptr->font_file_id = NO_FILE;
  2377.         }
  2378.     else if (!( (G_noverbatim) || (G_quiet) ) )
  2379.         fprintf(stderr,"%d: using font <%s>\n",
  2380.         plusid,tfontptr->name);
  2381.  
  2382.     tfontptr->plusid = plusid;
  2383.     plusid++;
  2384.  
  2385.     /* sprintf(tfontptr->psname,"%s.%ld.%d",
  2386.        tfontptr->n,tfontptr->font_mag,tfontptr->plusid);*/
  2387.  
  2388. #ifdef LJ
  2389.     if (plusid >= HANDLE_MAX_FONTS)
  2390.         Fatal("can handle only %d fonts! ask a wizzard..\n",
  2391.                HANDLE_MAX_FONTS);
  2392. #endif
  2393.     if (tfontptr != pfontptr) {
  2394.         if (font_found) OpenFontFile();
  2395.         else
  2396.             pxlfp = NO_FILE;
  2397.     }
  2398. #ifdef USEPXL
  2399.     if ( pxlfp == NO_FILE ) {        /* allow missing pxl files */
  2400.         tfontptr->magnification = 0;
  2401.         tfontptr->designsize = 0;
  2402. #endif
  2403.         for (i = FIRSTFNTCHAR; i <= LASTFNTCHAR; i++) {
  2404.             tcharptr = &(tfontptr->ch[i]);
  2405. #ifdef USEPXL
  2406.             tcharptr->width = 0;
  2407.             tcharptr->height = 0;
  2408.             tcharptr->xOffset = 0;
  2409.             tcharptr->yOffset = 0;
  2410. #endif
  2411.             tcharptr->where.isloaded = FALSE;
  2412.             tcharptr->where.address.fileOffset = NONEXISTANT;
  2413.             tcharptr->tfmw = 0;
  2414.         }
  2415. #ifdef USEPXL
  2416.         return;
  2417.     }
  2418.     t = (long) NoSignExtend(pxlfp, 1);
  2419.     if (t == 0) {
  2420.         t = (long) NoSignExtend(pxlfp, 1);
  2421.         t = (long) NoSignExtend(pxlfp, 2);
  2422.         if (t == 1002)
  2423.             tfontptr->id = id1002;
  2424.         else if (t == 1001)
  2425.             tfontptr->id = id1001;
  2426.         else
  2427.             Fatal("Unknown Version of PXL-format\n");
  2428.     } else {
  2429.         if (t == PK_PRE)    {
  2430.             unsigned char   temp_byte;
  2431.             temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  2432.             if (temp_byte != PK_ID) Fatal(
  2433.                "Wrong Version of pk file!  (%d should be 89)\n",
  2434.                              (int)temp_byte);
  2435.             else
  2436.                 tfontptr->id = pk89;
  2437.         } else
  2438.             Fatal("unknown font format in file <%s> !\n",fontptr->name);
  2439.     }
  2440.  
  2441.     if ((tfontptr->id == id1002) || (tfontptr->id == id1001)) {
  2442.         fseek(pxlfp, -20l, 2);
  2443.  
  2444.         t = NoSignExtend(pxlfp, 4);
  2445.         if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
  2446.     Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX",
  2447.                           tfontptr->name, tfontptr->c, t);
  2448.         tfontptr->magnification = NoSignExtend(pxlfp, 4);
  2449.         tfontptr->designsize    = NoSignExtend(pxlfp, 4);
  2450.  
  2451.         if (tfontptr->id == id1001)
  2452.             fseek(pxlfp, (long) (NoSignExtend(pxlfp, 4) * 4), 0);
  2453.         else
  2454.             fseek(pxlfp, (long) NoSignExtend(pxlfp, 4) , 0);
  2455.  
  2456.         for (i = FIRSTFNTCHAR; i <= LASTFNTCHAR; i++) {
  2457.             tcharptr = &(tfontptr->ch[i]);
  2458.             tcharptr->width   = (unsigned short) NoSignExtend(pxlfp, 2);
  2459.             tcharptr->height  = (unsigned short) NoSignExtend(pxlfp, 2);
  2460.             tcharptr->xOffset = (short) SignExtend(pxlfp, 2);
  2461.             tcharptr->yOffset = (short) SignExtend(pxlfp, 2);
  2462.             tcharptr->where.isloaded = FALSE;
  2463.             if (tfontptr->id == id1001)
  2464.                 tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4) * 4;
  2465.             else
  2466.                 tcharptr->where.address.fileOffset = NoSignExtend(pxlfp,4);
  2467.             tcharptr->tfmw = (long)
  2468.             (   (double)(NoSignExtend(pxlfp, 4))
  2469.               * (double)tfontptr->s / (double) 0x100000 );
  2470.             tcharptr->cw = (long)(((double)tcharptr->tfmw/(double)hconv) + 0.5);
  2471.  
  2472.             if (tcharptr->width  > CHAR_WIDTH_LARGE  ||
  2473.                 tcharptr->height > CHAR_HEIGTH_LARGE )
  2474.                 tcharptr->charsize = LARGE_SIZE;
  2475.             else
  2476.                 tcharptr->charsize = SMALL_SIZE;
  2477. #ifdef LJ
  2478.             max(tfontptr->max_width,tcharptr->width);
  2479.             max(tfontptr->max_height,tcharptr->height);
  2480.             if (tcharptr->yOffset > 0)
  2481.                 max(tfontptr->max_yoff,tcharptr->yOffset);
  2482.             if ((depth = tcharptr->height - tcharptr->yOffset)>max_depth)
  2483.                    max_depth = depth;
  2484. #endif
  2485.  
  2486.         }
  2487. #ifdef LJ
  2488.         tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
  2489.                                            tfontptr->max_yoff+1;
  2490. #endif
  2491.     } else { /* PK 89 format */
  2492.         unsigned char   temp_byte;
  2493.         register unsigned char  flag_byte;
  2494.         long    hppp, vppp, pkloc, packet_length, temp;
  2495.         int     car, ii;
  2496.  
  2497.         /* read comment */
  2498.         for ( ii = temp_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  2499.               ii>0; ii--) {
  2500.             flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  2501. #ifdef DEBUG
  2502.             if (Debug) fprintf(stderr, "%c", flag_byte ) ;
  2503. #endif
  2504.         }
  2505. #ifdef DEBUG
  2506.         if (Debug) fprintf(stderr, "\n");
  2507. #endif
  2508.         pkloc = 3 + (int)temp_byte;
  2509.         tfontptr->designsize = NoSignExtend(pxlfp, 4);
  2510.  
  2511.         t = NoSignExtend(pxlfp, 4);
  2512.         if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
  2513.           Warning("font = \"%s\",\n->tfm checksum = %lX,\n->pxl checksum = %lX",
  2514.                  tfontptr->name, tfontptr->c, t);
  2515.  
  2516.         hppp = NoSignExtend(pxlfp, 4);
  2517.         vppp = NoSignExtend(pxlfp, 4);
  2518.         if (hppp != vppp)
  2519.             Warning("aspect ratio is %ld:%ld (should be 1:1)!", hppp,vppp);
  2520.         tfontptr->magnification = (long)(hppp * 72.27 * 5 / 65536l + 0.5);
  2521.  
  2522.         pkloc += 16;
  2523.         flag_byte = skip_specials(&pkloc);
  2524.  
  2525.         while (flag_byte != PK_POST) {
  2526.         if ((flag_byte & 7) == 7) {
  2527.         /* fprintf(stderr,"\nRead long character preamble\n"); */
  2528.  
  2529.            packet_length = (unsigned long)NoSignExtend(pxlfp,4);
  2530.            if ((car = (int)NoSignExtend(pxlfp, 4)) > (LASTFNTCHAR))
  2531.                 Fatal("Bad character (%d) in PK-File\n",(int)car) ;
  2532.  
  2533.            tcharptr = &(tfontptr->ch[car]);
  2534.            tcharptr->where.address.fileOffset = pkloc;
  2535.            /* set pkloc to end_of_packet */
  2536.            pkloc += packet_length + 8;
  2537.  
  2538.            tcharptr->tfmw = (long) NoSignExtend(pxlfp, 4);
  2539.            (void) NoSignExtend(pxlfp, 4); /* horesc not used */
  2540.            (void) NoSignExtend(pxlfp, 4); /* not used */
  2541.  
  2542.            tcharptr ->width   = (unsigned short) NoSignExtend(pxlfp, 4);
  2543.            tcharptr ->height  = (unsigned short) NoSignExtend(pxlfp, 4);
  2544.            tcharptr ->xOffset = (short) SignExtend(pxlfp, 4);
  2545.            tcharptr ->yOffset = (short) SignExtend(pxlfp, 4);
  2546.            tcharptr ->where.isloaded = FALSE;
  2547.         } else if (flag_byte & 4) {
  2548.             /* fprintf(stderr,"Read extended short character preamble\n"); */
  2549.  
  2550.             packet_length = ((long) flag_byte & 3) * 65536l +
  2551.                 (unsigned short) NoSignExtend(pxlfp, 2);
  2552.             if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
  2553.                 Fatal("Bad character (%d) in PK-File\n",(int)car) ;
  2554.  
  2555.             tcharptr = &(tfontptr->ch[car]);
  2556.             tcharptr->where.address.fileOffset = pkloc;
  2557.             /* set pkloc to end_of_packet */
  2558.             pkloc += packet_length + 3;
  2559.  
  2560.             tcharptr->tfmw = (long) NoSignExtend(pxlfp, 3);
  2561. /*
  2562.             { register unsigned short t;
  2563.               t = (unsigned short) NoSignExtend(pxlfp, 1);
  2564.               tcharptr->tfmw = t * 65536l +
  2565.               (unsigned short) NoSignExtend(pxlfp, 2);
  2566.             }
  2567. */
  2568.             /* horesc not used */
  2569.             (void) NoSignExtend(pxlfp, 2) ;
  2570.             tcharptr ->width   = (unsigned short) NoSignExtend(pxlfp,2);
  2571.             tcharptr ->height  = (unsigned short) NoSignExtend(pxlfp,2);
  2572.             tcharptr ->xOffset = (short) SignExtend(pxlfp, 2);
  2573.             tcharptr ->yOffset = (short) SignExtend(pxlfp, 2);
  2574.             tcharptr ->where.isloaded = FALSE;
  2575.         } else {
  2576.             /* fprintf(stderr,"<Read short character preamble@>\n"); */
  2577.  
  2578.             packet_length = ((long)flag_byte & 3) * 256 +
  2579.                 NoSignExtend(pxlfp, 1) ;
  2580.             if ((car = (int)NoSignExtend(pxlfp, 1)) > (LASTFNTCHAR))
  2581.                 Fatal("Bad character (%d) in PK-File\n",(int)car) ;
  2582.  
  2583.             tcharptr = &(tfontptr->ch[car]);
  2584.             tcharptr->where.address.fileOffset = pkloc;
  2585.             /* set pkloc to end_of_packet */
  2586.             pkloc += packet_length + 2 ;
  2587.  
  2588.             tcharptr->tfmw = (long) NoSignExtend(pxlfp, 3);
  2589. /*
  2590.             { register unsigned short t;
  2591.               t = (unsigned short) NoSignExtend(pxlfp, 1);
  2592.               tcharptr->tfmw = t * 65536l +
  2593.               (unsigned short) NoSignExtend(pxlfp, 2);
  2594.             }
  2595. */
  2596.             /* horesc not used */
  2597.             (void) NoSignExtend(pxlfp, 1) ;
  2598.             tcharptr ->width   = (unsigned short) NoSignExtend(pxlfp,1);
  2599.             tcharptr ->height  = (unsigned short) NoSignExtend(pxlfp,1);
  2600.             tcharptr ->xOffset = (short) SignExtend(pxlfp, 1);
  2601.             tcharptr ->yOffset = (short) SignExtend(pxlfp, 1);
  2602.             tcharptr ->where.isloaded = FALSE;
  2603.         }
  2604.  
  2605.         tcharptr->tfmw = (long)
  2606.            ( tcharptr->tfmw * (double)tfontptr->s / (double) 0x100000 );
  2607.  
  2608.         tcharptr->cw = (long)(((double)tcharptr->tfmw /
  2609.             (double)hconv) + 0.5);
  2610.  
  2611.         if (tcharptr->width  > CHAR_WIDTH_LARGE  ||
  2612.             tcharptr->height > CHAR_HEIGTH_LARGE )
  2613.             tcharptr->charsize = LARGE_SIZE;
  2614.         else
  2615.             tcharptr->charsize = SMALL_SIZE;
  2616.  
  2617. #ifdef LJ
  2618.         max(tfontptr->max_width, tcharptr->width);
  2619.         max(tfontptr->max_height,tcharptr->height);
  2620.         if (tcharptr->yOffset > 0)
  2621.             max(tfontptr->max_yoff,tcharptr->yOffset);
  2622.         if ((depth = tcharptr->height - tcharptr->yOffset) > max_depth)
  2623.                 max_depth = depth;
  2624. #endif
  2625. /*
  2626. fprintf(stderr,"char=%d, tcharptr=%lx, flag_byte=%d, font=%lx\n",car, tcharptr,flag_byte,tfontptr);
  2627. */
  2628.         tcharptr->flag_byte = flag_byte;
  2629.         fseek(pxlfp, (long) pkloc, 0);
  2630.         flag_byte = skip_specials(&pkloc);
  2631.  
  2632.         } /* end of while */
  2633. #ifdef LJ
  2634. tfontptr->max_height = max_depth ? tfontptr->max_yoff+max_depth :
  2635.                                    tfontptr->max_yoff+1;
  2636. #endif
  2637. /*
  2638. printf("fontid=%d: max_width=%u, max_height=%d, max_yoff=%u\n",
  2639.         tfontptr->plusid, tfontptr->max_width,
  2640.         tfontptr->max_height, tfontptr->max_yoff);
  2641. */
  2642. #else
  2643.     if ( pxlfp == NO_FILE )        /* allow missing pxl files */
  2644.     return;
  2645.  
  2646.     gfin = pxlfp;
  2647.     seekpost();
  2648.     readpost();
  2649.     if ((tfontptr->c != 0) && (checksum != 0) && (tfontptr->c != checksum))
  2650.     Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d",
  2651.         tfontptr->name, tfontptr->c, checksum);
  2652.  
  2653.     for(i=FIRSTFNTCHAR; i<=LASTFNTCHAR; i++) {
  2654.     if (char_exists[i]) {
  2655.         tcharptr = &(tfontptr->ch[i]);
  2656.         tcharptr->tfmw = (long)(((float)tfm_wd[i]*(float)tfontptr->s) /
  2657.            (float)((long)1l<<20));
  2658.         tcharptr->where.address.fileOffset = char_pointer[i];
  2659.       }
  2660. #ifdef LJ
  2661. /*                 GF USER PLEASE CHECK IF THIS CODE WORKS
  2662.     tfontptr->max_width = gf_font_max_m;
  2663.     tfontptr->max_height = gf_font_max_n;
  2664.     tfontptr->max_yoff = gf_font_min_n;
  2665. */
  2666. #endif
  2667. #endif
  2668. /*****************************************************************************/
  2669. /*if (tcharptr->charsize==LARGE_SIZE)                                        */
  2670. /*     printf("%d:\t <%c> w=%d h=%d xO=%d yO=%d tfmw=%ld cw=%ld %d\n",       */
  2671. /*     i,(char) i,                                                           */
  2672. /*     tcharptr->width,tcharptr->height,tcharptr->xOffset,tcharptr->yOffset, */
  2673. /*     tcharptr->tfmw, tcharptr->cw, (int)(tcharptr->charsize));             */
  2674. /*                                                                           */
  2675. /*****************************************************************************/
  2676.     }
  2677.   }
  2678.  
  2679.  
  2680. unsigned char
  2681. skip_specials( pkloc )
  2682. long    *pkloc;
  2683. {
  2684.     long    i, j;
  2685.     register unsigned char  flag_byte;
  2686.     do {
  2687.     flag_byte = (unsigned char) NoSignExtend(pxlfp, 1);
  2688. /*
  2689. fprintf(stderr,"flagbyte = %d, pkloc=%ld\n",(int)flag_byte,*pkloc);
  2690. */
  2691.  
  2692.     (*pkloc) ++;
  2693.     if (flag_byte  >= 240)
  2694.         switch (flag_byte) {
  2695.         case 240:
  2696.         case 241:
  2697.         case 242:
  2698.         case 243 : {
  2699.             i = 0 ;
  2700.             for (j = 240; j <= (long)flag_byte; j++) {
  2701.                 i = 256 * i + NoSignExtend(pxlfp, 1) ;
  2702.                 (*pkloc) ++;
  2703.             }
  2704.             for (j = 1; j <= i; j++) {
  2705.                 (void) NoSignExtend(pxlfp, 1) ;
  2706.                 (*pkloc) ++;
  2707.             }
  2708.             break;
  2709.         }
  2710.         case 244 : {
  2711.             i = NoSignExtend(pxlfp, 4);
  2712.             (*pkloc) += 4;
  2713.             break;
  2714.         }
  2715.         case 245 :
  2716.             break;
  2717.         case 246 :
  2718.             break ;
  2719.         case 247:
  2720.         case 248:
  2721.         case 249:
  2722.         case 250:
  2723.         case 251:
  2724.         case 252:
  2725.         case 253:
  2726.         case 254:
  2727.         case 255: {
  2728.             Fatal("Unexpected flagbyte %d!\n",
  2729.                  (int)flag_byte) ;
  2730.             }
  2731.         }
  2732.     } while (!((flag_byte < 240) || (flag_byte == PK_POST))) ;
  2733.     return(flag_byte);
  2734. }
  2735.  
  2736.  
  2737. /*-->ReadPostAmble*/
  2738. /**********************************************************************/
  2739. /**************************  ReadPostAmble  ***************************/
  2740. /**********************************************************************/
  2741. /***********************************************************************
  2742.     This  routine  is  used  to  read  in  the  postamble  values.    It
  2743.     initializes the magnification and checks  the stack height prior  to
  2744.     starting printing the document.
  2745. ***********************************************************************/
  2746. void
  2747. ReadPostAmble(load)
  2748. bool load;
  2749. {
  2750.     FindPostAmblePtr (&postambleptr);
  2751.     if (NoSignExtend(dvifp, 1) != POST)
  2752.         Fatal ("POST missing at head of postamble");
  2753. #ifdef DEBUG
  2754.     if (Debug)
  2755.         fprintf(stderr,"got POST command\n");
  2756. #endif
  2757.     ppagep = NoSignExtend(dvifp, 4);
  2758.     num = NoSignExtend(dvifp, 4);
  2759.     den = NoSignExtend(dvifp, 4);
  2760.     mag = NoSignExtend(dvifp, 4);
  2761.     if ( usermag > 0 && usermag != mag )
  2762.         Warning("DVI magnification of %ld over-ridden by user (%ld)",
  2763.                      mag, usermag );
  2764.     if ( usermag > 0 )
  2765.         mag = usermag;
  2766.     hconv = DoConv(num, den, hconvRESOLUTION);
  2767.     vconv = DoConv(num, den, vconvRESOLUTION);
  2768.     (void) NoSignExtend(dvifp, 4);   /* height-plus-depth of tallest page */
  2769.     (void) NoSignExtend(dvifp, 4);   /* width of widest page */
  2770.     if (NoSignExtend(dvifp, 2) >= STACK_SIZE)
  2771.         Fatal ("Stack size is too small");
  2772.     (void) NoSignExtend(dvifp, 2);   /* this reads the number of pages in */
  2773.                      /* the DVI file */
  2774. #ifdef DEBUG
  2775.     if (Debug)
  2776.         fprintf(stderr,"now reading font defs");
  2777. #endif
  2778.     if (load)
  2779.         GetFontDef ();
  2780. }
  2781.  
  2782.  
  2783. /*-->LoadAChar*/
  2784. /**********************************************************************/
  2785. /***************************** LoadAChar ******************************/
  2786. /**********************************************************************/
  2787. void
  2788. LoadAChar(c, ptr)
  2789. long    c;
  2790. register struct char_entry *ptr;
  2791. {
  2792.     long    *pr;
  2793.     long    bytes;
  2794.  
  2795.     if (ptr->where.address.fileOffset == NONEXISTANT) {
  2796.         ptr->where.isloaded = FALSE;
  2797.         return;
  2798.     }
  2799.  
  2800.     OpenFontFile();
  2801.  
  2802. #ifdef DEBUG
  2803.     if (Debug)
  2804.       fprintf(stderr, "LoadAChar: <%c>(%ld) from file at pos %ld\n",
  2805.           (char)c,c,ptr->where.address.fileOffset);
  2806. #endif
  2807.  
  2808. #ifdef USEPXL
  2809.  
  2810.     fseek(pxlfp, ptr->where.address.fileOffset, 0);
  2811.  
  2812.     if (fontptr->id == pk89) {
  2813. #ifdef PARANOIA
  2814.         unsigned char   temp;
  2815.         temp = (unsigned char) NoSignExtend(pxlfp, 1);
  2816.  
  2817.         if ((int)(ptr->flag_byte) != (int)temp) {
  2818.            fprintf(stderr,"font=%lx, ptr=%lx\n",fontptr,ptr);
  2819.                 Fatal("%d: ,oh boy! old flag %d, new flag %d, ptr=%lx\n",
  2820.                           (int)c,(int)(ptr->flag_byte),(int)temp,ptr);
  2821.             }
  2822. #endif
  2823.  
  2824.         if ((ptr->flag_byte & 7) == 7) {
  2825.             bytes = ((long) NoSignExtend(pxlfp, 4)) - 28;
  2826.             fseek(pxlfp, ptr->where.address.fileOffset + 36, 0);
  2827. /*
  2828. fprintf(stderr,"bytes=%d, seeking at %ld\n",
  2829.             bytes, ptr->where.address.fileOffset + 36);
  2830. */
  2831.         } else if ((ptr->flag_byte & 4) == 4) {
  2832.             bytes = ((long)ptr->flag_byte & 3)
  2833.                 * 65536l + NoSignExtend(pxlfp, 2) - 13;
  2834.             fseek(pxlfp, ptr->where.address.fileOffset + 16, 0);
  2835.         } else {
  2836.             bytes = ((long)ptr->flag_byte & 3)
  2837.                 * 256 + NoSignExtend(pxlfp, 1) - 8;
  2838.             fseek(pxlfp, ptr->where.address.fileOffset + 10, 0);
  2839.         }
  2840.     } else if (fontptr->id == id1002)
  2841.         bytes =  ((( (long)ptr->width + 7) >> 3) * (long) ptr->height);
  2842.     else if (fontptr->id == id1001)
  2843.         bytes =  4 * (((long)ptr->width + 31) >> 5) * (long)ptr->height;
  2844.  
  2845.     if (bytes > 0) {
  2846.                                           /* do NOT load Huge characters */
  2847.       if ((bytes > HUGE_CHAR_PATTERN) && (fontptr->id != pk89)) {
  2848.     qfprintf(stderr,"Huge Character <%c> (%ld Bytes)\n", (char)c, bytes);
  2849.         ptr->charsize = HUGE_SIZE;
  2850.         ptr->where.isloaded = FALSE;
  2851.       } else {
  2852.         if ( (pr = (long *)malloc( bytes )) == NULL )
  2853.             Fatal("Unable to allocate %ld bytes for char <%c>\n",
  2854.                          bytes, (char)c);
  2855. /*
  2856.  * else fprintf(stderr,"allocating %ld bytes char <%c>(%d)\t at 0x%lx\n",
  2857.  *                       bytes, (char)c,(int)c,pr);
  2858.  */ 
  2859. #ifdef DEBUG
  2860.         if (Debug)
  2861.           fprintf(stderr,
  2862.            "Allocating Char <%c>, FileOffset=%lX, Bytes=%ld (%d) <%d>\n",
  2863.               (char) c, ptr->where.address.fileOffset, bytes,
  2864.               (int)bytes, (unsigned int)bytes);
  2865. #endif
  2866.         allocated_storage += bytes;
  2867.         fread(pr, 1, (int) bytes , pxlfp);
  2868.         ptr->where.address.pixptr = pr;
  2869.       }
  2870.     } 
  2871. #else
  2872.     fseek(gfin, ptr->where.address.fileOffset, 0);
  2873.     gettochar();
  2874.     readbits();
  2875.     if (num_bytes > HUGE_CHAR_PATTERN)
  2876.       ptr->charsize = HUGE_SIZE;
  2877. #endif
  2878.     ptr->where.isloaded = TRUE;
  2879.     if ((ptr->charsize != SMALL_SIZE)
  2880. #ifdef LJ
  2881.          || (rasterfont[fontptr->plusid])
  2882. #endif
  2883.        )
  2884.         return;
  2885.  
  2886.     EmitChar(c, ptr);
  2887. #ifdef USEPXL
  2888.     /* we should really free the space used by the PXL data after this
  2889.        point, but it is not large, and besides, we may want to be
  2890.        more clever in the future, about sending bitmaps.  So keep
  2891.        the data around */
  2892. #endif
  2893. }
  2894. /*-->SetChar*/
  2895. /**********************************************************************/
  2896. /*****************************  SetChar  ******************************/
  2897. /**********************************************************************/
  2898. void
  2899. SetChar(c, command, PassNo, do_posn,in_string)
  2900. long    c;
  2901. short   command;
  2902. int     PassNo;
  2903. bool do_posn,in_string;
  2904. {
  2905.     register struct char_entry *ptr;  /* temporary char_entry pointer */
  2906.     bool pos_after = FALSE;
  2907.  
  2908.     ptr = &(fontptr->ch[c]);
  2909.     if (!((ptr->where.isloaded) || (ptr->charsize == HUGE_SIZE)))
  2910.         LoadAChar(c, ptr);
  2911.     if (PassNo == 0)
  2912.         return;
  2913.  
  2914.     if (do_posn) {
  2915. #ifdef IBM3812
  2916.         if (CharStringPos>0) {
  2917.             fprintf(stderr,"!!!! That should never happen!!!\n");
  2918.             CharStringOut;
  2919.         }
  2920. #endif
  2921.         SetPosn(h, v);
  2922.     }
  2923. /*
  2924. printf("(%d) hh=%ld (+%ld/+%ld), h=%ld, xh=%ld,xhh=%ld, [%ld|%ld] ->%d\n",
  2925.     (int)do_posn,hh,(long)ptr->cw,(long)ptr->cw*(long)hconv,h,
  2926.     PIXROUND(h, hconv),
  2927.     PIXROUND(hh, hconv),
  2928.     labs((hh-h)),hconv,(labs((hh-h))>hconv)
  2929.     );
  2930. */
  2931.     if (in_string && (labs((hh-h))>hconv)) {
  2932. #ifdef IBM3812
  2933.         CharStringOut;
  2934. #endif
  2935.         SetPosn(h, v);
  2936.     }
  2937.  
  2938.     if (fontptr->font_file_id != NO_FILE) {      /* ignore missing fonts */
  2939.         if ((ptr->charsize != SMALL_SIZE)
  2940. #ifdef LJ
  2941.          || (rasterfont[fontptr->plusid])
  2942. #endif
  2943.            ) {
  2944.             int     tmp;
  2945.             char    sign;
  2946.  
  2947. #ifdef LJ
  2948.             if (!do_posn)
  2949.                 SetPosn(h, v);
  2950. #ifdef USEPXL
  2951.             tmp = (int) -ptr->yOffset;
  2952. #else
  2953.             tmp = (int) num_rows-y_offset;
  2954. #endif
  2955.             if (tmp != 0) {
  2956.                if (tmp < 0) {
  2957.                    sign = '-'; tmp = -tmp;
  2958.                } else
  2959.                    sign = '+';
  2960.                EMIT(outfp, "\033*p%c%dY", sign, tmp);
  2961.             }
  2962. #ifdef USEPXL
  2963.             tmp = (int) -ptr->xOffset;
  2964. #else
  2965.             tmp = (int) -x_offset;
  2966. #endif
  2967.             if (tmp != 0) {
  2968.                if (tmp < 0) {
  2969.                    sign = '-'; tmp = -tmp;
  2970.                } else
  2971.                    sign = '+';
  2972.                EMIT(outfp, "\033*p%c%dX", sign, tmp);
  2973.             }
  2974. #endif
  2975. #ifdef IBM3812
  2976.             CharStringOut;
  2977. #endif
  2978. #ifdef DEBUG
  2979.     if (Debug)
  2980.         fprintf(stderr,"Raster character <%c> %hd\n", (char) c,(short)c);
  2981. #endif
  2982.             RasterChar(ptr);
  2983.             pos_after = TRUE;
  2984.         } else {
  2985. #ifdef IBM3812
  2986. #ifdef USEPXL
  2987.             if ( ptr->yyOffset || (!in_string) ) {
  2988.                 CharStringOut;
  2989.                 MoveVert(ptr->yyOffset);
  2990.                 sprintf(PMPformat, "\01%c", (unsigned char)c);
  2991.                 PMPout(2, PMPformat);
  2992.                 MoveVert((int)-(ptr->yyOffset));
  2993.             } else {
  2994. #endif
  2995.                 if (CharStringPos==CHARSTRINGMAX)
  2996.                     CharStringOut;
  2997.  
  2998.                 CharString[CharStringPos]=(unsigned char)c;
  2999.                 CharStringPos++;
  3000. #ifdef USEPXL
  3001.             }
  3002. #endif
  3003. #endif
  3004. #ifdef LJ
  3005. #define TRANSPARENTCHAR(c) \
  3006.         if ((c == 0l) || (c >= 7l && c <= 15l) || (c == 27l)) \
  3007.         EMIT(outfp, "\033&p1X%c", (unsigned char)c); \
  3008.         else EMITC((unsigned char)c)
  3009. #ifdef USEPXL
  3010.             if (ptr->yyOffset) {
  3011.                 EMIT(outfp, "\033*p+%hdY", ptr->yyOffset);
  3012.                 TRANSPARENTCHAR(c);
  3013.                 EMIT(outfp, "\033*p-%hdY", ptr->yyOffset);
  3014.             } else
  3015. #endif
  3016. /*                EMITC( (unsigned char)c);*/
  3017.                { TRANSPARENTCHAR(c);}
  3018. #endif
  3019.         }
  3020.         hh += (long) ptr->cw*hconv;
  3021.     }
  3022.     if (command <= SET4)
  3023.         h += ptr->tfmw;
  3024.     if (pos_after)
  3025.         SetPosn(h, v);
  3026. }
  3027.  
  3028.  
  3029. void
  3030. DoBop()
  3031. {
  3032.     struct font_entry *p;
  3033. #ifdef LJ
  3034.     register short i;
  3035.     if (fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
  3036.        for (i = 0; i < HANDLE_MAX_FONTS; i++)
  3037.           rasterfont[i] = FALSE;
  3038.     }
  3039.     fonts_used_on_this_page = 0;
  3040. #endif
  3041.     for (p = hfontptr; p; p = p->next) {
  3042.         p->used_on_this_page = FALSE;
  3043.     }
  3044. }
  3045.  
  3046.  
  3047. /*-->SetFntNum*/
  3048. /**********************************************************************/
  3049. /****************************  SetFntNum  *****************************/
  3050. /**********************************************************************/
  3051. void
  3052. SetFntNum(k, Emitting)
  3053. long    k;
  3054. bool Emitting;
  3055. /*  this routine is used to specify the font to be used in printing future
  3056.     characters */
  3057. {
  3058. #ifdef LJ
  3059.     static unsigned short plusid = 0;
  3060. #endif
  3061.     fontptr = hfontptr;
  3062.     while ((fontptr != NULL) && (fontptr->k != k))
  3063.         fontptr = fontptr->next;
  3064.     if (fontptr == NULL)
  3065.         Fatal("font %ld undefined", k);
  3066.     if (Emitting && (fontptr->font_file_id != NO_FILE) ) {
  3067.         if (!fontptr->used_on_this_page) {
  3068.             fontptr->used_on_this_page = TRUE;
  3069. #ifdef LJ
  3070.             if (++fonts_used_on_this_page > MAX_FONTS_PER_PAGE) {
  3071.               qfprintf(stderr,"this is the %d. font on this page!",
  3072.                        fonts_used_on_this_page);
  3073.               qfprintf(stderr," (max = %d) rastering characters!\n",
  3074.                        MAX_FONTS_PER_PAGE);
  3075.                rasterfont[fontptr->plusid] = TRUE;
  3076.             }
  3077. #endif
  3078.         }
  3079.  
  3080.         /* activate font */
  3081. #ifdef IBM3812
  3082.         sprintf(PMPformat, "\323%c", (unsigned char)fontptr->plusid);
  3083.         PMPout(2, PMPformat);
  3084. #endif
  3085. #ifdef LJ
  3086.         if (!rasterfont[fontptr->plusid]) {
  3087.             if (fontptr->plusid>0) EMIT(outfp, "\033(%dX", fontptr->plusid);
  3088.             else                   EMIT(outfp, "\033(X");
  3089.         }
  3090. /* else printf("I am doing rasterfont for plusid=%d instead\n",
  3091.                 fontptr->plusid);
  3092. */
  3093. #endif
  3094.     }
  3095. #ifdef LJ    /* reassignment of printer font id  0.48 */
  3096.     else if (fontptr->font_file_id != NO_FILE) {
  3097.             if (fontptr->ncdl == 0) {
  3098. #ifdef DEBUG
  3099.         printf("Changing plusid from %d to %d\n", fontptr->plusid, (int)plusid);
  3100. #endif
  3101.                 fontptr -> plusid = plusid;
  3102.                 plusid ++;
  3103.             }
  3104.     }
  3105. #endif
  3106. }
  3107.  
  3108.  
  3109. /*-->SetPosn*/
  3110. /**********************************************************************/
  3111. /*****************************  SetPosn  ******************************/
  3112. /**********************************************************************/
  3113. void                  /* output a positioning command */
  3114. SetPosn(x, y)
  3115. long    x, y;
  3116. {
  3117.     int     rx, ry;
  3118.     rx = (int)PIXROUND(x, hconv) + x_goffset;
  3119.     ry = (int)PIXROUND(y, vconv) + y_goffset;
  3120.  
  3121. /*
  3122.  * printf("setposn to %d/%d\n",rx,ry);
  3123.  */
  3124.  
  3125. #ifdef IBM3812
  3126.     PMPcont(3);
  3127.     PMPoutC('\340');
  3128.     EMITWORD(LARGER(rx,0));
  3129.  
  3130.     if (last_ry != ry) { /* necessary to set new y-position */
  3131.         PMPcont(3);
  3132.         PMPoutC('\341');
  3133.         EMITWORD(LARGER(ry,0));
  3134.     }
  3135. #endif
  3136. #ifdef LJ
  3137.     if (last_ry != ry)   /* necessary to set new y-position */
  3138.         EMIT(outfp, "\033*p%dx%dY", LARGER(rx,0), LARGER(ry,0));
  3139.     else
  3140.         EMIT(outfp, "\033*p%dX", LARGER(rx,0));
  3141. #endif
  3142.  
  3143.     last_ry = ry;    /* last y-position on output device */
  3144.     last_rx = rx;    /* last x-position on output device */
  3145. /*
  3146.  * must know where device "really" is horizontally, for rel. posning.
  3147.  * (maybe in the future), but we always use direct positioning for
  3148.  * vertical movement.
  3149.  */
  3150.     /* hh = rx * hconv; */
  3151.     hh = x;
  3152.     vv = y;
  3153. /*
  3154.  *     fprintf(stderr,"DoPosn: x=%ld, y=%ld, rx=%d, ry=%d, hh=%ld, vv=%ld\n",
  3155.  *               x,y,rx,ry,hh,vv);
  3156.  */
  3157. }
  3158.  
  3159.  
  3160. #ifdef IBM3812
  3161. /*-->PMPLine*/
  3162. /**********************************************************************/
  3163. /*****************************  PMPLine  ******************************/
  3164. /**********************************************************************/
  3165. void       /* drawing lines on the 3812 using PMP vector commands */
  3166. PMPLine(w, y, x)
  3167. int     w, y, x;
  3168. {
  3169.  
  3170.     if ((w == 0) || ((x == 0) && (y == 0)))
  3171.         return;
  3172.  
  3173. /*
  3174. fprintf(stderr,"w=%d / %d - %d, y=%d / %d - %d, x=%d / %d - %d\n",
  3175.         w,(char)(w & 0xff),(int)((signed_char)(w & 0xff)),
  3176.         y,(char)(y & 0xff),(int)((signed_char)(y & 0xff)),
  3177.         x,(char)(x & 0xff),(int)((signed_char)(x & 0xff)));
  3178. */
  3179.  
  3180.     if ( (((signed_char)(x & 0xff)) == x ) &&
  3181.         ( ((signed_char)(y & 0xff)) == y ) ) {
  3182.         PMPcont(6);
  3183.         PMPout(1, "\370");
  3184.         EMITWORD(3);      /* length of vector */
  3185.         PMPoutC((unsigned char)(0x80 | 0x00 | (unsigned char) w));
  3186.         PMPoutC((signed_char)(y & 0xff));
  3187.         PMPoutC((signed_char)(x & 0xff));
  3188. /*
  3189.         fprintf(stderr,"F8 00 03: w=%d, x=%d(%d-%.2X), y=%d(%d-%.2X),\n",
  3190.         w,x,(char)(x & 0xff),(signed_char)(x & 0xff),
  3191.           y,(char)(y & 0xff),(signed_char)(y & 0xff));
  3192. */
  3193.  
  3194.     } else {
  3195.         PMPcont(8);
  3196.         PMPout(1, "\370");
  3197.         EMITWORD(4 + 1);      /* length of vector */
  3198.         PMPoutC((unsigned char)(0xC0 | 0x00 | (unsigned char) w));
  3199.         EMITWORD(y);
  3200.         EMITWORD(x);
  3201. /*
  3202.         fprintf(stderr,"F8 00 05: w=%d, x=%d, y=%d,\n", w,x,y);
  3203. */
  3204.     }
  3205. }
  3206.  
  3207.  
  3208. #endif
  3209. /*-->SetRule*/
  3210. /**********************************************************************/
  3211. /*****************************  SetRule  ******************************/
  3212. /**********************************************************************/
  3213. void                   /*   this routine will draw a rule */
  3214. SetRule(a, b, Set)
  3215. long    a, b;
  3216. int     Set;
  3217. {
  3218.     long    xx, yy;
  3219.     short   hor_offset, vert_offset, ll;
  3220.  
  3221.     if ( a > 0 && b > 0 ) {
  3222.         SetPosn(h, v);             /* lower left corner */
  3223.         xx = (long)PIXROUND(b, hconv);     /* width */
  3224.         yy = (long)PIXROUND(a, vconv);     /* height */
  3225.  
  3226. #ifdef DEBUG
  3227.         if (Debug)
  3228.             fprintf(stderr,"Rule xx=%ld, yy=%ld\n", xx, yy);
  3229. #endif
  3230.  
  3231.         hor_offset  = (short)(last_ry - yy);
  3232.         if (hor_offset < 0) yy += hor_offset;
  3233.         if (last_rx < 0) xx += last_rx;
  3234.  
  3235. #ifdef IBM3812
  3236.         if (Landscape) {
  3237.           if (last_ry > MAX_PAGE_WIDTH) yy += MAX_PAGE_WIDTH-last_ry;
  3238.           hor_offset  = (short)(MAX_PAGE_HEIGHT - (last_rx + xx));
  3239.         } else {
  3240.           if (last_ry > MAX_PAGE_HEIGHT) yy += MAX_PAGE_HEIGHT-last_ry;
  3241.           hor_offset  = (short)(MAX_PAGE_WIDTH - (last_rx + xx));
  3242.         }
  3243.         if (hor_offset < 0) xx += hor_offset;
  3244.  
  3245.         if ((xx > 31) && (yy > 31)) {
  3246. /*
  3247.  *   fill area by multiple lines  (kind of a mess)
  3248.  *   process for simplicity always horizontally
  3249.  */
  3250.  
  3251. /* printf("large box: w=%d, x=%d, y=%d\n",(int)yy,(int)xx,0);*/
  3252.  
  3253.             hor_offset  = HOR_HALF(30);
  3254.             MoveHor(hor_offset);
  3255.             vert_offset = VERT_HALF(30);
  3256.             MoveVert(-vert_offset);
  3257.             ll = (short)xx - 30;
  3258.  
  3259.             for (; yy > 30; yy -= 30) {
  3260.                 PMPLine(30, 0, ll);
  3261.                 MoveHor(-ll);
  3262.                 MoveVert(-30);
  3263.             }
  3264.  
  3265.             hor_offset  = -hor_offset     + HOR_HALF(yy);
  3266.             MoveHor(hor_offset);
  3267.             vert_offset = (vert_offset - 30) + VERT_HALF(yy);
  3268.             MoveVert(-vert_offset);
  3269.  
  3270.             PMPLine((int)yy, 0, (int)(xx - yy));
  3271.  
  3272.         } else if ( (yy < xx) && (xx > 0) ) {
  3273.  
  3274. /* printf("hori rule: w=%d, x=%d, y=%d\n",(int)yy,(int)(xx-yy),0);*/
  3275.  
  3276.             hor_offset  = HOR_HALF(yy);
  3277.             vert_offset = VERT_HALF(yy);
  3278.  
  3279.             MoveHor(hor_offset);
  3280.             MoveVert(-vert_offset);
  3281.  
  3282.             PMPLine((int)yy, 0, (int)(xx - yy));
  3283.         } else if ( (xx < yy) && (yy > 0)) {
  3284.  
  3285.             hor_offset  = HOR_HALF(xx);
  3286.             vert_offset = VERT_HALF(xx);
  3287. /*
  3288.  printf("move: x=%d, y=%d\n",hor_offset,-vert_offset);
  3289.  printf("vert rule: w=%d, x=%d, y=%d\n",(int)xx,0,(int)-(yy-xx));
  3290. */
  3291.             MoveHor(hor_offset);
  3292.             MoveVert(-vert_offset);
  3293.  
  3294.             PMPLine((int)xx, (int)-(yy - xx), 0);
  3295.         } else if (xx == yy) {
  3296.             short     y0;  /* small square box!! */
  3297.  
  3298.             y0 = (short)yy / 2;
  3299.             hor_offset  = HOR_HALF(y0);
  3300.             MoveHor(hor_offset);
  3301.             vert_offset = VERT_HALF(y0);
  3302.             MoveVert(-vert_offset);
  3303.             ll = (short)xx - y0;
  3304.  
  3305.             PMPLine((int)y0, 0, ll);
  3306.  
  3307.             hor_offset  = -(ll + hor_offset);
  3308.             vert_offset = (y0 - vert_offset);
  3309.  
  3310.             yy -= (long)y0;
  3311.             hor_offset  += HOR_HALF(yy);
  3312.             MoveHor(hor_offset);
  3313.             vert_offset += VERT_HALF(yy);
  3314.             MoveVert(-vert_offset);
  3315.  
  3316.             PMPLine((int)yy, 0, (int)xx - yy);
  3317.         }
  3318. #endif
  3319. #ifdef LJ
  3320.         if ((pgsiz_dots >0) && (last_ry > pgsiz_dots))
  3321.                 yy += (long)pgsiz_dots - (long)last_ry;
  3322.  
  3323.         if ((yy>0) && (xx>0))
  3324.                 EMIT(outfp, "\033*p-%ldY\033*c%lda%ldbP", yy - 1, xx, yy);
  3325. #endif
  3326.         last_ry = UNKNOWN;       /* next time full positioning */
  3327.     }
  3328.     if (Set)
  3329.         h += b;
  3330. }
  3331.  
  3332.  
  3333. /*-->SetString*/
  3334. /**********************************************************************/
  3335. /*****************************  SetString  ****************************/
  3336. /**********************************************************************/
  3337. void
  3338. SetString(firstch, PassNo)    /* read and set a consecutive string of chars */
  3339. short   firstch;
  3340. int     PassNo;
  3341. {
  3342.     short   c;
  3343.     register unsigned short i;
  3344.  
  3345. #ifdef DEBUG
  3346.     if (Debug)
  3347.       fprintf(stderr, "SetString ");
  3348. #endif
  3349.     for (i = 0, c = firstch; c >= SETC_000 && c <= SETC_127; i++) {
  3350. #ifdef DEBUG
  3351.         if (Debug)
  3352.           fprintf (stderr, "%d ", c);
  3353. #endif
  3354.         SetChar((long)c,  c, PassNo, (bool)(i==0),TRUE);
  3355.         c = (short) NoSignExtend(dvifp, 1);
  3356.     }
  3357.     fseek(dvifp, -1l, 1);    /* backup one character */
  3358. #ifdef IBM3812
  3359.     CharStringOut;
  3360. #endif
  3361. #ifdef DEBUG
  3362.     if (Debug)
  3363.       fprintf(stderr, "...SetString\n");
  3364. #endif
  3365. }
  3366.  
  3367.  
  3368. /*-->SignExtend*/
  3369. /**********************************************************************/
  3370. /****************************  SignExtend  ****************************/
  3371. /**********************************************************************/
  3372. long
  3373. SignExtend(fp, n)   /* return n byte quantity from file fd */
  3374. register FILE *fp;  /* file pointer    */
  3375. register int    n;  /* number of bytes */
  3376. {
  3377.     int     n1;     /* number of bytes      */
  3378.     long    x;      /* number being constructed */
  3379.     x = getc(fp);   /* get first (high-order) byte */
  3380.     n1 = n--;
  3381.     while (n--)  {
  3382.         x <<= 8;
  3383.         x |= getc(fp);
  3384.     }
  3385. /*
  3386.  *   NOTE: This code assumes that the right-shift is an arithmetic, rather
  3387.  *   than logical, shift which will propagate the sign bit right.   According
  3388.  *   to Kernighan and Ritchie, this is compiler dependent!
  3389.  */
  3390.     x <<= 32 - 8 * n1;
  3391.     x >>= 32 - 8 * n1; /* sign extend */
  3392. #ifdef DEBUG
  3393.     if (Debug)
  3394.         fprintf(stderr,"\tSignExtend(fp,%d)=%X\n", n1, x);
  3395. #endif
  3396.     return(x);
  3397. }
  3398.  
  3399.  
  3400. /*-->SkipFontDef*/
  3401. /**********************************************************************/
  3402. /****************************  SkipFontDef  ***************************/
  3403. /**********************************************************************/
  3404. void
  3405. SkipFontDef()
  3406. {
  3407.     int     a, l;
  3408.     char    n[STRSIZE];
  3409.  
  3410.     (void) NoSignExtend(dvifp, 4);
  3411.     (void) NoSignExtend(dvifp, 4);
  3412.     (void) NoSignExtend(dvifp, 4);
  3413.     a = (int) NoSignExtend(dvifp, 1);
  3414.     l = (int) NoSignExtend(dvifp, 1);
  3415.     GetBytes(dvifp, n, a + l);
  3416. }
  3417.  
  3418.  
  3419. /*-->Warning*/
  3420. /**********************************************************************/
  3421. /*****************************  Warning  ******************************/
  3422. /**********************************************************************/
  3423. void                           /* issue a warning */
  3424. Warning(fmt, a, b, c, d)
  3425. char    *fmt;         /* format    */
  3426. char    *a, *b, *c, *d;   /* arguments */
  3427. {
  3428.     G_errenc = 1;
  3429.     if ( G_nowarn || G_quiet )
  3430.         return;
  3431.  
  3432.     fprintf(stderr, "warning : ");
  3433.     fprintf(stderr, fmt, a, b, c, d);
  3434.     fprintf(stderr, "\n");
  3435. }
  3436.  
  3437. void
  3438. PutWord(w)
  3439. int     w;
  3440. {
  3441.     EMITC((char)(w >> 8) & 0xff);
  3442.     EMITC((char)w & 0xff);
  3443. }
  3444.  
  3445.  
  3446. #ifdef IBM3812
  3447. /*-->PMPout*/
  3448. /*****************************************************************************/
  3449. /* This routine produces the PMP-envelopes for the 3812. Its semantics are:
  3450.  
  3451.    first arg == 0  ... flush buffer
  3452.    first arg == -1 ... number of bytes specified in the second argument
  3453.                have to be continuous, that is they must not
  3454.                be disrupted by ENTER PMP etc.
  3455.    first arg > 0       output first arg bytes
  3456.  
  3457.                If arg2 > OUTBUFSIZE ... flush buffer,
  3458.                         switch to unbuffered mode
  3459.                         (dont't collect PMP commands)
  3460.                If arg2+bufferpointer > OUTBUFSIZE ... flush buffer,
  3461.                         block will fit into buffer
  3462.                otherwise ..... block will fit into buffer
  3463.  
  3464.   Buffering is done to reduce the ENTER PMP-commands. Initially
  3465.   the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is
  3466.   necessary to enter PMP mode. The ENTER-PMP-command contains the
  3467.   number of bytes that will be interpreted as PMP-commands. In the
  3468.   most naive approach for each primitive command (eg. set cursor) you
  3469.   have to produce a seperate ENTER-PMP-envelope (5 bytes). It is
  3470.   favourable to collect as many PMP commands as possible in one envelope. */
  3471. /*****************************************************************************/
  3472. void
  3473. PMPout(l, s)
  3474. char    *s;
  3475. int     l;
  3476. {
  3477.     static char     buffer[OUTBUFSIZE];
  3478.     static unsigned short   bp = 0;         /* range 0..OUTBUFSIZE */
  3479.     static long     continuous = 0l;
  3480.     static bool buffered = TRUE;
  3481.  
  3482.     if (l == 0) {
  3483.         if (bp == 0)
  3484.             return;
  3485.         EMIT(outfp, "\033[C%c%c", (unsigned char)(bp & 0xFF),
  3486.             (unsigned char)(bp >> 8));
  3487.         EMITB((int)bp, buffer);
  3488.         bp = 0;
  3489.         return;
  3490.     }
  3491.     if (l == -1) {
  3492.         continuous = (long)s;
  3493.         if (continuous + (long)bp + 5l > (long) OUTBUFSIZE)
  3494.             PMPflush;
  3495.         buffered = (bool) ((continuous + 5l <= (long) OUTBUFSIZE));
  3496.         if (!buffered) {
  3497.             EMIT(outfp, "\033[C%c%c",
  3498.                 (unsigned char)(continuous & 0xFF),
  3499.                 (unsigned char)((continuous >> 8) & 0xFF));
  3500.         }
  3501.         return;
  3502.     }
  3503.     if (buffered) {
  3504.         register int    i;
  3505.         if ( ((long)l + bp) > OUTBUFSIZE)
  3506.             PMPflush;
  3507.         for (i = 0; i < l; i++)
  3508.             buffer[bp+i] = s[i];
  3509.         bp += (unsigned short)l;
  3510.     } else {
  3511.         EMITB((int)l, s);
  3512.         buffered = (bool) ((continuous -= (long)l) <= 0) ;
  3513.     }
  3514. }
  3515.  
  3516.  
  3517. void
  3518. PMPoutC(c)
  3519. char    (c);
  3520. {
  3521.     PMPout(1, &c);
  3522. }
  3523.  
  3524.  
  3525. #endif
  3526. #ifdef MSDOS
  3527. /*-->AssureBinary*/
  3528. /**********************************************************************/
  3529. /*************************** AssureBinary *****************************/
  3530. /**********************************************************************/
  3531. /* This procedure is both DOS AND MSC dependent. The MSC file open on */
  3532. /* a device ignores the 'binary' of the "wb" parameter and opens the  */
  3533. /* file in ascii mode. This procedure sets the file f to binary mode  */
  3534. /* if it is connected to a device that is not console input or output */
  3535. /* or the null device. For other operating systems this routine is    */
  3536. /* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */
  3537. /**********************************************************************/
  3538. void
  3539. AssureBinary(f)
  3540. FILE *f;
  3541. {
  3542.     union REGS regs;              /* registers for bios call */
  3543.  
  3544.     regs.h.ah = (unsigned char) 0x44;     /* IOCTL            */
  3545.     regs.h.al = (unsigned char) 0x00;     /* get device information   */
  3546.     regs.x.bx = (unsigned int) fileno(f); /* handle from MSC      */
  3547.     intdos(®s, ®s);         /* call DOS interrupt       */
  3548.                           /* ---> result in DX    */
  3549.  
  3550.     if (  (regs.h.dl & 0x80)     /* file handle points to a device */
  3551.          && !(regs.h.dl & 0x07) )    /* neither console i/o or null    */ {
  3552.  
  3553.         regs.h.dl  |= 0x20;      /* set BINARY bit in device info  */
  3554.  
  3555.         regs.h.ah = (unsigned char) 0x44;    /* IOCTL         */
  3556.         regs.h.al = (unsigned char) 0x01;    /* set device information*/
  3557.         regs.x.bx = (unsigned int) fileno(f); /* handle from MSC      */
  3558.         regs.h.dh = (unsigned char) 0x00;    /* clear DH          */
  3559.         intdos(®s, ®s);           /* call DOS interrupt     */
  3560.     }
  3561. }
  3562.  
  3563.  
  3564. #endif
  3565.  
  3566. #ifdef USEPXL
  3567. bool getbit ();
  3568. unsigned char   getnyb ();
  3569. long    pk_packed_num ();
  3570.  
  3571.  
  3572. #define  PKBYTE   *pkloc; pkloc ++
  3573. #define  OUTCHAR(c) raster_line_buf[bp]= (unsigned char)c; bp++
  3574.  
  3575. unsigned char   bitweight, inputbyte ;
  3576. unsigned char   dyn_f ;
  3577. unsigned char   *pkloc;
  3578. int     repeatcount;
  3579.  
  3580. void              /* <Read and translate raster description@>*/
  3581. PkRaster(ce, raster)
  3582. struct char_entry *ce;
  3583. bool raster;
  3584. {
  3585.     int     rp;
  3586.     int     current_line;
  3587.     int     wordwidth ;
  3588.     bool turnon;
  3589.     unsigned short  nbpl;
  3590.     long    rowsleft, word, wordweight, hbit, count, i, j, tl;
  3591.     long    row[101] ;
  3592.     unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
  3593.     unsigned short  bp;
  3594.  
  3595.  
  3596.     if (ce->charsize == HUGE_SIZE)
  3597.         Fatal( "cannot process currently PK font patterns of that size!\n");
  3598.  
  3599.  
  3600.     current_line = 0;
  3601.     pkloc = (unsigned char *)ce->where.address.pixptr;
  3602.     dyn_f = (unsigned char)(ce->flag_byte >> 4);
  3603.     turnon = (bool)((ce->flag_byte & 8) == 8);
  3604.     wordwidth = (int)(ce->width + 31) >> 5 ;
  3605.     nbpl = ((ce->width) +  7) >> 3;
  3606.  
  3607.     bitweight = 0 ;
  3608.     if (dyn_f == 14) {
  3609.         /*printf("<Get raster by bits@>\n");*/
  3610.         for (i = 1; i <= (long)ce->height; i++) {
  3611.         word = 0 ;
  3612.         wordweight = 31 ;
  3613.         bp = 0;            /* Sowa */
  3614.  
  3615. #ifdef DRAWGLYPH
  3616.            printf("     |");
  3617. #endif
  3618.         for (j = 1; j <= (long) ce->width; j++) {
  3619.             bool getbit;
  3620.             /* bp = 0;               SOWA/
  3621. /*******************************************begin Getbit *********/
  3622.             bitweight /= 2 ;
  3623.             if ( bitweight == 0 ) {
  3624.                 inputbyte = PKBYTE ;
  3625.                 bitweight = 128 ;
  3626.             }
  3627.             getbit = (bool)
  3628.              ( inputbyte >= bitweight ) ;
  3629.             if ( getbit )
  3630.                 inputbyte -= bitweight ;
  3631. /*********************************************end Getbit *********/
  3632.  
  3633.             if (getbit)
  3634.                 word += power[wordweight] ;
  3635.  
  3636.             wordweight --;
  3637.             if (wordweight == -1) {
  3638.  
  3639. #ifdef DRAWGLYPH
  3640.    { int k;
  3641.      for (k=31; k>=0; k--) {
  3642.          if ((power[k] & word)!=0) printf("M");
  3643.          else printf(".");
  3644.      }
  3645.    }
  3646. #endif
  3647.  
  3648.             OUTCHAR((word >> 24 & 0xFF));
  3649.             OUTCHAR((word >> 16 & 0xFF));
  3650.             OUTCHAR((word >> 8 & 0xFF));
  3651.             OUTCHAR((word    & 0xFF));
  3652.  
  3653.             word = 0 ;
  3654.             wordweight = 31 ;
  3655.             }
  3656.         }
  3657.         if (wordweight < 31) {
  3658. #ifdef COMMENT
  3659. #ifdef DRAWGLYPH
  3660.    { int k;
  3661.      for (k=15; k>=0; k--) {
  3662.         if ((power[k] & word)!=0) printf("Z");
  3663.         else printf(":");
  3664.      }
  3665.     }
  3666.     printf("|\n ----|");
  3667. #endif
  3668. #endif
  3669.  
  3670.             for (j = 3; j >= (wordwidth * 4 - (long)nbpl);
  3671.             j--) {
  3672.  
  3673.                 OUTCHAR(((word >> (j << 3)) & 0xff));
  3674.  
  3675. #ifdef DRAWGLYPH
  3676.    { int k;
  3677.      for (k=7; k>=0; k--) {
  3678.         if ((power[k] & ((word >> (j << 3)) & 0xff))!=0) printf("M");
  3679.         else printf(".");
  3680.      }
  3681.    }
  3682. #endif
  3683.  
  3684.             }
  3685.         }
  3686.  
  3687.         if (raster) {
  3688.             RasterLine(ce, (unsigned int)nbpl,
  3689.                 current_line, raster_line_buf);
  3690.             current_line++;
  3691.         } else
  3692.             EMITL(bp, raster_line_buf);
  3693.  
  3694. #ifdef DRAWGLYPH
  3695.    printf("|\n");
  3696. #endif
  3697.         }
  3698.     } else {
  3699.         /* printf("@<Create normally packed raster@>\n"); */
  3700.         rowsleft = (long) ce->height ;
  3701.         hbit = (long) ce->width ;
  3702.         repeatcount = 0 ;
  3703.         wordweight = 32 ;
  3704.         word = 0 ;
  3705.         rp = 1 ;
  3706.         while ( rowsleft > 0 ) {
  3707.         count = pk_packed_num() ;
  3708.         bp = 0;
  3709.  
  3710.         while (count > 0) {
  3711.             if ((count < wordweight) && (count < hbit)) {
  3712.             if (turnon)
  3713.                 word +=
  3714.                     gpower[wordweight] -
  3715.                     gpower[wordweight - count] ;
  3716.  
  3717.             hbit -= count ;
  3718.             wordweight -= count ;
  3719.             count = 0 ;
  3720.             } else if ((count >= hbit) && (hbit <=
  3721.             wordweight)) {
  3722.  
  3723.             if (turnon)
  3724.                 word +=
  3725.                     gpower[wordweight] -
  3726.                     gpower[wordweight - hbit] ;
  3727.  
  3728.             row[rp] = word ;
  3729.  
  3730.             /* printf(" @<Send row@> \n");*/
  3731.             for (i = 0; i <= (long) repeatcount; i++) { int ii;
  3732.  
  3733. #ifdef DRAWGLYPH
  3734.   printf("***  |");
  3735. #endif
  3736.                 for (ii = 1; ii < wordwidth; ii++) {
  3737.                 tl = row[ii];
  3738.  
  3739.                 OUTCHAR((tl >> 24 & 0xFF));
  3740.                 OUTCHAR((tl >> 16 & 0xFF));
  3741.                 OUTCHAR((tl >> 8  & 0xFF));
  3742.                 OUTCHAR((tl       & 0xFF));
  3743.  
  3744. #ifdef DRAWGLYPH
  3745.    { int k;
  3746.      for (k=31; k>=0; k--)  {
  3747.          if ((power[k] & row[ii])!=0) printf("M");
  3748.          else printf(".");
  3749.      }
  3750.    }
  3751. #endif
  3752.                 }
  3753.                 tl = row[wordwidth];
  3754.                 for (j = 3; j >= (wordwidth *4 - (long)nbpl);
  3755.                  j--) {
  3756.  
  3757.                  OUTCHAR(((tl >> (j << 3)) & 0xff));
  3758.  
  3759. #ifdef DRAWGLYPH
  3760.    { int k;
  3761.      for (k=7; k>=0; k--) {
  3762.          if ((power[k] & ((tl >> (j << 3)) & 0xff))!=0) printf("M");
  3763.          else printf(".");
  3764.      }
  3765.    }
  3766. #endif
  3767.                 }
  3768.  
  3769.                 if (raster) {
  3770.                     RasterLine(ce,
  3771.                     (unsigned int)nbpl,
  3772.                      current_line,
  3773.                      raster_line_buf);
  3774.                     current_line++;
  3775.                 } else
  3776.                     EMITL(bp, raster_line_buf);
  3777.  
  3778.                 bp = 0;
  3779.  
  3780. #ifdef DRAWGLYPH
  3781.    printf("|  ");
  3782.    for (j=1;j<=(long)wordwidth;j++) printf("%02lX/",row[j]);
  3783.    printf(" raster=%d\n",raster);
  3784. #endif
  3785.             }
  3786.  
  3787.             rowsleft -=  (long)repeatcount + 1 ;
  3788.             repeatcount = 0 ;
  3789.             rp = 1 ;
  3790.             word = 0 ;
  3791.             wordweight = 32 ;
  3792.             count -= hbit ;
  3793.             hbit = (long)ce->width ;
  3794.             } else {
  3795.             if (turnon) word += gpower[wordweight] ;
  3796.             row[rp] = word ;
  3797.             rp = rp + 1 ;
  3798.             word = 0 ;
  3799.             count -= wordweight ;
  3800.             hbit -= wordweight ;
  3801.             wordweight = 32 ;
  3802.             }
  3803.         }   /* .....while count > 0 */
  3804.         if (turnon)
  3805.             turnon = FALSE;
  3806.         else
  3807.             turnon = TRUE;
  3808.         } /* ...... rowsleft > 0 */
  3809.         if ((rowsleft != 0) || (hbit != (long)ce->width))
  3810.             Fatal("Bad pk file----more bits than required!\n");
  3811.     } /* .... create normally packed raster */
  3812. }
  3813.  
  3814.  
  3815. unsigned char   getnyb ()
  3816. {
  3817.     register unsigned char  temp ;
  3818.     if ( bitweight == 0 ) {
  3819.         inputbyte = PKBYTE ;
  3820.         bitweight = 16 ;
  3821.     }
  3822.     temp = inputbyte / bitweight ;
  3823.     inputbyte -= temp * bitweight ;
  3824.     bitweight /= 16 ;
  3825.     return ( temp ) ;
  3826. }
  3827.  
  3828.  
  3829. long
  3830. pk_packed_num ()
  3831. { /*@<Packed number procedure@>= */
  3832.     register int    i;
  3833.     long    j;
  3834.  
  3835.     i = (int)getnyb();
  3836.     if (i == 0) {
  3837.         do {
  3838.             j = (long)getnyb();
  3839.             i++;
  3840.         } while (j == 0) ;
  3841.         while (i > 0) {
  3842.             j = j * 16 + (long)getnyb() ;
  3843.             i--;
  3844.         };
  3845.         return (j - 15 + (13 - dyn_f) * 16 + dyn_f) ;
  3846.     } else if (i <= (int)dyn_f) {
  3847.         return ((long)i);
  3848.     } else if (i < 14) {
  3849.         return ((i-(long)dyn_f - 1) * 16 + (long)getnyb() + dyn_f + 1);
  3850.     } else {
  3851.         if (i == 14) {
  3852.             repeatcount = (int) pk_packed_num() ;
  3853.         } else {
  3854.             repeatcount = 1 ;
  3855.         }
  3856.         /*      printf("repeatcount = [%d]\n",repeatcount);    */
  3857.         return (pk_packed_num()) ;    /* tail end recursion !! */
  3858.     }
  3859. }
  3860. #endif  
  3861.  
  3862. #ifndef USEPXL
  3863. void bad_gf(n)
  3864.     int n;
  3865. {
  3866.     Fatal("Bad gf file, case %d\n",n);      /* See gf.c */
  3867. }
  3868. #endif
  3869. /*-->FormFeed*/
  3870. /**********************************************************************/
  3871. /*****************************  FormFeed ******************************/
  3872. /**********************************************************************/
  3873. void
  3874. FormFeed()
  3875. {
  3876.  
  3877. #ifdef IBM3812
  3878.     unsigned short pages;
  3879.     if ( (ndone == 0) && (FirstAlternate)){
  3880.         for (pages = 1; pages < ncopies; pages++) {
  3881.             PMPout(2, "\321\300"); /* PMP-command xD1C0 */
  3882.         }
  3883.         PMPout(2, "\321\100"); /* PMP-command xD140 */
  3884.     } else {
  3885.         for (pages = 1; pages < ncopies; pages++){
  3886.             PMPout(2, "\321\200"); /* PMP-command xD180 */
  3887.         }
  3888.         PMPout(2, "\321\0"); /* PMP-command xD100 */
  3889.     }
  3890. #endif
  3891. #ifdef LJ
  3892.     EMITC('\f');
  3893. #endif
  3894. }
  3895.