home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Dvi / dvieps.arc / DVIEPS.C < prev    next >
C/C++ Source or Header  |  1988-10-16  |  20KB  |  713 lines

  1. /* -*-C-*- dvieps.c */
  2. /*-->dvieps*/
  3. /**********************************************************************/
  4. /******************************* dvieps *******************************/
  5. /**********************************************************************/
  6.  
  7. /***********************************************************************
  8. DVIEPS was  developed from  one  of the  dot-matrix printer  drivers  by
  9. Marcus  Moehrmann  (EMAIL:   marcus%fkihh@unido.uucp).   The   following
  10. remarks are his.
  11.  
  12. This is an implementation for  Epson and compatible printers.   Printers
  13. with 9 needles are supported; those with 24 are not. I hope that I  have
  14. only used the ESC/P-Standard.  The only documentation I  have had was  a
  15. description for the NEC Pinwriter P6/P7,  but our printer is a  Logitec,
  16. which I used for testing.
  17.  
  18. There is a difference in paper feeding, because the P6/P7-handbook  says
  19. that
  20.  
  21.     <ESC> J (n)
  22.  
  23. performs n/180 inch paper feeding,  but our printer performs n/216  inch
  24. paper feeding, which I think is the standard, so I have used this in the
  25. driver.
  26.  
  27. For horizontal resolution I have used the Esc-sequences
  28.  
  29.     <ESC> * (m) (n1) (n2)        [m = 0, 1, 2, 3]
  30.  
  31. instead of
  32.  
  33.     <ESC> (x) (n1) (n2)        [x = 'K', 'L', 'Y', 'Z']
  34.  
  35. If this  will  not work  on  your  printer, change  the  definitions  of
  36. 'EPSON_BIT_IMAGE' and 'EPSON_MICRO_STEP'  and the variable  'resolution'
  37. in procedure 'outline'.
  38.  
  39. Be careful with the reset command
  40.  
  41.     <ESC> @
  42.  
  43. I have done this before any printing, and then after about 1.5 pages the
  44. printer stopped. The same works quite well on a second printer.
  45.  
  46. Specialities: There is a switch '-t' for twice-a-line printing, that is,
  47. print one  line in  1/120  inch horizontal  spacing, return  print  head
  48. without paper feeding,  perform a  1/240 inch  step and  then print  the
  49. second line with 1/120 inch spacing.
  50.  
  51. ***********************************************************************/
  52.  
  53. #include "dvihead.h"
  54.  
  55. /**********************************************************************/
  56. /************************  Device Definitions  ************************/
  57. /**********************************************************************/
  58.  
  59. /* All output-device-specific definitions go here.  This section must
  60. be changed when modifying a dvi driver for use on a new device */
  61.  
  62. #undef EPSON
  63. #define EPSON    1            /* conditional compilation flag */
  64.  
  65. #define VERSION_NO    "2.10 [experimental]"    /* DVI driver version number */
  66.  
  67. #undef HIRES
  68. #define  HIRES          1        /* 0 for 72-dpi version */
  69.  
  70. #if    HIRES
  71. #define  DEVICE_ID    "Epson 9-pin family 240/216-dpi matrix printer"
  72.                     /* this string is printed at runtime */
  73. #define OUTFILE_EXT    "eps"
  74.  
  75. #define  XDPI        240        /* horizontal dots/inch */
  76. #define  YDPI        216        /* vertical dots/inch */
  77.  
  78. #else /* NOT HIRES */
  79. #define  DEVICE_ID    "Epson 9-pin family 60/72-dpi matrix printer"
  80.                     /* this string is printed at runtime */
  81.  
  82. #define OUTFILE_EXT    "e72"
  83.  
  84. #define  XDPI        60        /* horizontal dots/inch */
  85. #define  YDPI        72        /* vertical dots/inch */
  86. #endif /* HIRES */
  87.  
  88. #define  BYTE_SIZE      8        /* output file byte size */
  89.  
  90. #undef STDRES
  91. #if    HIRES
  92. #define STDRES  1            /* 0 for low-resolution devices */
  93. #else /* NOT HIRES */
  94. #define STDRES  0            /* 0 for low-resolution devices */
  95. #endif /* HIRES */
  96.  
  97. #define  XPSIZE        8        /* horizontal paper size in inches */
  98. #define  XSIZE        (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\
  99.                 (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE))
  100.                     /* number of horizontal dots; */
  101.                     /* MUST BE multiple of */
  102.                     /* 2*HOST_WORD_SIZE */
  103. #define  XWORDS        ((XSIZE + HOST_WORD_SIZE - 1)/HOST_WORD_SIZE)
  104.                     /* number of words in rows  */
  105.                     /* of bitmap array */
  106.  
  107. #define  YPSIZE        11        /* vertical paper size in inches */
  108. #define  YSIZE        (YDPI*YPSIZE)    /* number of vertical dots */
  109.  
  110. #if    HIRES
  111. INT16 paperfeeding;            /* outstanding 1/216 inch */
  112.                     /* form-feedings */
  113.  
  114. BOOLEAN twice_a_line = FALSE;        /* this is runtime option '-t' */
  115.                     /* print in 1/120-inch-mode, */
  116.                     /* 2nd line shifted 1/240 inch */
  117.  
  118.                     /* need single-arg outline() */
  119. BOOLEAN micro_step;            /* used in outline() */
  120. #define OUTLINE(v,flag) {micro_step = flag; outline(v);}
  121. #endif /* HIRES */
  122.  
  123. /* The printer bit map. */
  124.  
  125. #define XBIT XWORDS
  126. #define YBIT YSIZE
  127.  
  128. #if    (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
  129. #undef SEGMEM
  130. #define SEGMEM 1        /* ( ((long)XBIT * (long)YBIT) > 65536L ) */
  131. #endif /* (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD) */
  132.  
  133. #define EPSON_ADV_PAPER        "\033J%c"    /* advance paper n/216 inch */
  134. #define EPSON_BIT_IMAGE        "\033*%c%c%c"
  135. #define EPSON_MICRO_STEP    OUTF2("\033*\003\001%c%c",'\000','\000')
  136.  
  137. #include "bitmap.h"
  138.  
  139. #include "main.h"
  140. #include "abortrun.h"
  141. #include "actfact.h"
  142. #include "alldone.h"
  143. #include "chargf.h"
  144. #include "charpk.h"
  145. #include "charpxl.h"
  146. #include "clrbmap.h"
  147. #include "clrrow.h"
  148. #include "dbgopen.h"
  149.  
  150. /*-->devinit*/
  151. /**********************************************************************/
  152. /****************************** devinit *******************************/
  153. /**********************************************************************/
  154.  
  155. void
  156. devinit(argc, argv)        /* initialize device */
  157. int argc;
  158. char *argv[];
  159. {
  160.     (void)getbmap();
  161.     if (runlengthcode && !quiet)
  162.     {
  163.     (void)fprintf(stderr, "[Run-length encoding of output file]");
  164.     NEWLINE(stderr);
  165.     }
  166.  
  167. #if    HIRES
  168.     if (twice_a_line && !quiet)
  169.     {
  170.     (void)fprintf(stderr, "[Twice-a-line-printing for high resolution]");
  171.     NEWLINE(stderr);
  172.     }
  173. #endif /* HIRES */
  174.  
  175. }
  176.  
  177. /*-->devterm*/
  178. /**********************************************************************/
  179. /****************************** devterm *******************************/
  180. /**********************************************************************/
  181.  
  182. void
  183. devterm()            /* terminate device */
  184. {
  185. }
  186.  
  187. #include "dispchar.h"
  188. #include "dvifile.h"
  189. #include "dviinit.h"
  190. #include "dviterm.h"
  191. #include "f20open.h"
  192. #include "fatal.h"
  193. #include "fillrect.h"
  194. #include "findpost.h"
  195. #include "fixpos.h"
  196. #include "fontfile.h"
  197. #include "fontsub.h"
  198. #include "getbmap.h"
  199. #include "getbytes.h"
  200. #include "getfntdf.h"
  201. #include "getpgtab.h"
  202. #include "inch.h"
  203. #include "initglob.h"
  204. #include "loadchar.h"
  205.  
  206. /*-->makechar*/
  207. /**********************************************************************/
  208. /****************************** makechar ******************************/
  209. /**********************************************************************/
  210.  
  211. char
  212. makechar(p, mask)
  213. register UNSIGN32 *p[];
  214. register UNSIGN32 mask;
  215. {
  216.     register char c;
  217.  
  218. #if    SEGMEM
  219. #define Q(n) p[n]        /* use precomputed pointers */
  220. #else /* NOT SEGMEM */
  221. #define Q(n) (p[0] - (n)*XBIT)    /* compute pointers on the fly */
  222. #endif /* SEGMEM */
  223.  
  224.     c = '\000';                /* MSB controls top needle */
  225.  
  226. #if    HIRES
  227.     if (*Q(0) & mask)
  228.     c |= '\200';
  229.     if (*Q(3) & mask)
  230.     c |= '\100';
  231.     if (*Q(6) & mask)
  232.     c |= '\040';
  233.     if (*Q(9) & mask)
  234.     c |= '\020';
  235.     if (*Q(12) & mask)
  236.     c |= '\010';
  237.     if (*Q(15) & mask)
  238.     c |= '\004';
  239.     if (*Q(18) & mask)
  240.     c |= '\002';
  241.     if (*Q(21) & mask)
  242.     c |= '\001';
  243. #else /* NOT HIRES */
  244.     if (*Q(0) & mask)
  245.     c |= '\200';
  246.     if (*Q(1) & mask)
  247.     c |= '\100';
  248.     if (*Q(2) & mask)
  249.     c |= '\040';
  250.     if (*Q(3) & mask)
  251.     c |= '\020';
  252.     if (*Q(4) & mask)
  253.     c |= '\010';
  254.     if (*Q(5) & mask)
  255.     c |= '\004';
  256.     if (*Q(6) & mask)
  257.     c |= '\002';
  258.     if (*Q(7) & mask)
  259.     c |= '\001';
  260. #endif /* HIRES */
  261.  
  262.     return (c);
  263. }
  264.  
  265. #include "movedown.h"
  266. #include "moveover.h"
  267. #include "moveto.h"
  268. #include "nosignex.h"
  269. #include "openfont.h"
  270. #include "option.h"
  271.  
  272. #if    HIRES
  273. /*-->outpaperfeed*/
  274. /**********************************************************************/
  275. /*************************** outpaperfeed *****************************/
  276. /**********************************************************************/
  277.  
  278. void
  279. outpaperfeed(count)        /* accumulate 1/216 inch paperfeedings */
  280. INT16 count;            /* and write them out if count == 0 */
  281. {
  282.  
  283.     register INT16 k;
  284.  
  285.     if (count)
  286.     paperfeeding += count;
  287.     else
  288.     {
  289.     for (k = paperfeeding / 255; k; --k)
  290.         OUTF(EPSON_ADV_PAPER, 255);
  291.     if ((k = paperfeeding % 255) > 0)
  292.         OUTF(EPSON_ADV_PAPER, k);
  293.     paperfeeding = 0;
  294.     }
  295. }
  296. #endif /* HIRES */
  297.  
  298. /*-->outline*/
  299. /**********************************************************************/
  300. /****************************** outline *******************************/
  301. /**********************************************************************/
  302.  
  303. void
  304. outline(pline)
  305. char *pline;
  306. {
  307.     register char* a;
  308.     register char* b;
  309.     register char* c;
  310.     register INT16 left;
  311.     INT16 len;
  312.     INT16 linelength;
  313.     char resolution;
  314.     BYTE spacing;
  315.     BYTE space_width;
  316.  
  317. #if    HIRES
  318.     if (twice_a_line)            /* step 1/240 inch forward */
  319.     {
  320.     resolution = '\001';        /* 1/120 */
  321.     space_width = 12;        /* 12/120 */
  322.     linelength = XSIZE / 2;
  323.     }
  324.     else
  325.     {
  326.     resolution = '\003';        /* 1/240 */
  327.     space_width = 24;        /* 24/240 */
  328.     linelength = XSIZE;
  329.     }
  330. #else /* NOT HIRES */
  331.     resolution = '\000';        /* 1/60 */
  332.     space_width = 6;            /* 6/60 */
  333.     linelength = XSIZE;
  334. #endif /* HIRES */
  335.  
  336.     for ((left = linelength, c = pline + linelength - 1);
  337.      (*c == '\000') && (left > 0);
  338.      (--left, --c))            /* trim white space */
  339.     ;
  340.  
  341.     if (left == 0)
  342.     return;        /* NEWLINE() is not needed for any paperfeeding */
  343.  
  344. #if    HIRES
  345.     (void)outpaperfeed(0);        /* print accumulated paperfeedings */
  346. #endif /* HIRES */
  347.  
  348.     /*******************************************************************
  349.     We search for runs as follows.  "b" marks the beginning of unwritten
  350.     data, and "a" anchors the beginning of a run which continues to just
  351.     before "c".   The  run length  is  "c"-"a".  Only  runs  longer than
  352.     "space_width" are taken, because we print spaces in text mode.  This
  353.     implies that the run only consists of '\000' characters.
  354.  
  355.     If a long  enough run  is found,  then the  string "b"  .. "a"-1  is
  356.     output since its length is now  known, followed by the run  encoding
  357.     for the character at "a".  Then "a" and "b" are advanced to "c", and
  358.     the scan continues.
  359.  
  360.     If the  run  beginning at  "a"  is too  short,  then "a"  is  simply
  361.     advanced.
  362.  
  363.     Since the  character strings  take on  all values  on 0  .. 255,  we
  364.     cannot store a termination marker, but must instead keep a  counter,
  365.     "left", which is  decremented to  0 when the  end of  the string  is
  366.     reached.
  367.  
  368.     ?????????????0000000000000000????????????????????
  369.     ^            ^               ^
  370.     |            |               |
  371.     b            a               c
  372.  
  373.                  <-----run------>
  374.  
  375.  
  376.     We cannot use fprintf %s because 0 bytes terminate string, so we are
  377.     using putc for writing the line.
  378.     *******************************************************************/
  379.  
  380.     if (runlengthcode && (left >= space_width))
  381.     {
  382.     for (a = b = pline; (left > 0); --left)
  383.     {
  384.         for (c = a; (*a == *++c) && (*a == '\000') && left; --left)
  385.         ;            /* advance over run */
  386.         len = (INT16) (c - a);    /* "c" points past run */
  387.  
  388.         if (len >= space_width)    /* output long run */
  389.         {
  390.         if (a > b)        /* output previous string */
  391.         {
  392. #if    HIRES
  393.             if (micro_step)
  394.             {
  395.             EPSON_MICRO_STEP;
  396.             micro_step = FALSE;
  397.             }
  398. #endif /* HIRES */
  399.             OUTF3(EPSON_BIT_IMAGE, resolution, ((int) (a - b)) % 256,
  400.               ((int) (a - b)) / 256);
  401.             for (; b < a; b++)
  402.             OUTC(*b);
  403.         }
  404.  
  405.         c -= len % space_width;    /* shorten run */
  406.         left += len % space_width;
  407.  
  408.         for (spacing = (BYTE)(len / space_width); spacing; --spacing)
  409.             OUTC(' ');        /* output run */
  410.  
  411.         a = b = c;
  412.         }
  413.         else            /* ignore short run */
  414.         {
  415.         ++a;
  416.         left += len - 1;
  417.         }
  418.     }                /* end for() loop */
  419.  
  420.     if (a > b)            /* output remaining string */
  421.     {
  422. #if    HIRES
  423.         if (micro_step)
  424.         {
  425.         EPSON_MICRO_STEP;
  426.         micro_step = FALSE;
  427.         }
  428. #endif /* HIRES */
  429.         OUTF3(EPSON_BIT_IMAGE,resolution,((int) (a - b)) % 256,
  430.           ((int) (a - b)) / 256);
  431.         for (; b < a; b++)
  432.         OUTC(*b);
  433.     }
  434.     }
  435.     else                /* no runlength coding */
  436.     if (left > 0)
  437.     {
  438. #if    HIRES
  439.     if (micro_step)
  440.     {
  441.         EPSON_MICRO_STEP;
  442.         micro_step = FALSE;
  443.     }
  444. #endif /* HIRES */
  445.     OUTF3(EPSON_BIT_IMAGE,resolution,left % 256,left / 256);
  446.     for (c = pline; left; --left, c++)
  447.         OUTC(*c);
  448.     }
  449.     NEWLINE(plotfp);
  450. }
  451.  
  452. #include "outrow.h"
  453.  
  454. /*-->prtbmap*/
  455. /**********************************************************************/
  456. /****************************** prtbmap *******************************/
  457. /**********************************************************************/
  458.  
  459. void
  460. prtbmap()
  461. {
  462.     register BYTE *c;            /* pointer into v8[][] and v8t[][][] */
  463.     UNSIGN32 *p;            /* pointer into bitmap[][] */
  464.  
  465. #if    SEGMEM
  466. #else /* NOT SEGMEM */
  467.     UNSIGN32 *ptmp;            /* pointer into bitmap[][] */
  468. #endif /* SEGMEM */
  469.  
  470.     register UNSIGN32 mask;        /* mask for single bit selection */
  471.     register INT16 k;
  472.     INT16 i;
  473.     INT16 j;
  474.     INT16 ybottom;
  475.     INT16 ytop;
  476.  
  477. #if    HIRES
  478.     BYTE v8[3][XSIZE];            /* vertical 8-bit raster encodings */
  479.     BYTE v8t[3][2][XSIZE / 2];        /* vertical 8-bit raster encodings */
  480.                     /* (twice-a-line) */
  481.     INT16 second = 0;            /* address second byte if not zero */
  482.  
  483. #undef Q
  484. #if    SEGMEM
  485.     UNSIGN32 *q[24];            /* pointers to 24 raster lines */
  486. #define Q(n) q[n]            /* use precomputed pointers */
  487. #else /* NOT SEGMEM */
  488. #define Q(n) (p - (n)*XBIT)        /* compute pointers on the fly */
  489. #endif /* SEGMEM */
  490.  
  491.     (void)clearerr(plotfp);
  492.  
  493.     ytop = YBIT - 1;
  494.  
  495.     k = -1;                /* find bottom non-zero raster */
  496.     for (j = 0; (j < ytop) && (k < 0); ++j)    /* loop over raster lines */
  497.     {
  498.  
  499. #if    IBM_PC_MICROSOFT
  500.     for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j, k) == 0)); --k)
  501.         ;                /* trim white space */
  502.  
  503. #else /* NOT IBM_PC_MICROSOFT */
  504.     p = BITMAP(j, XBIT - 1);
  505.     for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
  506.         --p;            /* trim white space */
  507. #endif /* IBM_PC_MICROSOFT */
  508.  
  509.     }
  510.     ybottom = (j / 24) * 24 + 23;
  511.  
  512.     paperfeeding = 0;            /* for outpaperfeed() */
  513.     OUTF("\0333%c", 0);            /* no paperfeeding */
  514.  
  515.     for (j = ytop; (j >= ybottom); j -= 24)    /* loop over raster lines */
  516.     {                    /* in groups of 24 */
  517.  
  518. #if    SEGMEM
  519. #else /* NOT SEGMEM */
  520.     p = BITMAP(j, 0);        /* the j-th raster line */
  521. #endif /* SEGMEM */
  522.  
  523.     if (twice_a_line)
  524.         c = &v8t[0][0][0];        /* vertical 8-bit encodings */
  525.     else
  526.         c = &v8[0][0];        /* vertical 8-bit encodings */
  527.  
  528.     for (i = 0; i < XBIT; (++p, ++i))    /* loop over raster words */
  529.     {
  530.         /* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
  531.            hard way, arghh... */
  532.         mask = 1;
  533.         mask <<= (HOST_WORD_SIZE - 1);    /* to select leftmost bit */
  534.  
  535. #if    SEGMEM
  536.         for (k = 0; k < 24; ++k)    /* compute pointers to 24 rasters */
  537.         q[k] = BITMAP(j - k, i);
  538. #endif /* SEGMEM */
  539.  
  540.         for (k = 0; k < HOST_WORD_SIZE; (++k)) /* loop over word bits */
  541.         {
  542.         /* examine bits in 24 adjacent rows and build two 8-bit */
  543.         /* character values, the first with rows n,n+3,...,n+21, */
  544.         /* the second with rows n+1,n+4,...,n+22, the third with */
  545.         /* rows n+2,n+5,...,n+23. The 2nd and 3rd characters are */
  546.         /* then printed with 1 dot vertical spacing. */
  547.  
  548.         /* if twice_a_line is TRUE, the bytes will be written */
  549.         /* alternating in v8t[x][0][y] and v8t[x][1][y] */
  550.  
  551.         if (twice_a_line)
  552.             second = (k % 2) * XSIZE / 2;
  553.  
  554. #if    SEGMEM
  555.         *(c + second) = (BYTE) makechar(&q[0], mask);
  556.         *(c + XSIZE + second) = (BYTE) makechar(&q[1], mask);
  557.         *(c + 2 * XSIZE + second) = (BYTE) makechar(&q[2], mask);
  558. #else /* NOT SEGMEM */
  559.         *(c + second) = (BYTE) makechar(&p, mask);
  560.         ptmp = p - XBIT;
  561.         *(c + XSIZE + second) = (BYTE) makechar(&ptmp, mask);
  562.         ptmp = p - 2 * XBIT;
  563.         *(c + 2 * XSIZE + second) = (BYTE) makechar(&ptmp, mask);
  564. #endif /* SEGMEM */
  565.  
  566.         if (twice_a_line)
  567.         {
  568.             if (second)
  569.             c++;        /* increment after second byte */
  570.         }
  571.         else
  572.             c++;
  573.  
  574.         mask >>= 1;        /* move masking bit right 1 position */
  575.         }                /* end loop over k */
  576.     }                /* end loop over i */
  577.  
  578.     if (twice_a_line)
  579.     {
  580.         OUTLINE((char *) &v8t[0][0][0], FALSE);
  581.         OUTLINE((char *) &v8t[0][1][0], TRUE);
  582.         (void)outpaperfeed(1);
  583.         OUTLINE((char *) &v8t[1][0][0], FALSE);
  584.         OUTLINE((char *) &v8t[1][1][0], TRUE);
  585.         (void)outpaperfeed(1);
  586.         OUTLINE((char *) &v8t[2][0][0], FALSE);
  587.         OUTLINE((char *) &v8t[2][1][0], TRUE);
  588.         (void)outpaperfeed(22);
  589.     }
  590.     else
  591.     {
  592.         OUTLINE((char *) &v8[0][0], FALSE);
  593.         (void)outpaperfeed(1);
  594.         OUTLINE((char *) &v8[1][0], FALSE);
  595.         (void)outpaperfeed(1);
  596.         OUTLINE((char *) &v8[2][0], FALSE);
  597.         (void)outpaperfeed(22);
  598.     }
  599.  
  600.     }                    /* end loop over j */
  601.  
  602.     OUTS("\0332");            /* ESC 2 = normal paperfeeding */
  603.     OUTC('\f');                /* eject page with FF */
  604.  
  605.     (void)fflush(plotfp);
  606.     if (DISKFULL(plotfp))
  607.     (void)fatal("prtbmap(): Output error -- disk storage probably full");
  608. }
  609.  
  610. #else /* NOT HIRES */
  611.     BYTE v8[XSIZE + 2];            /* vertical 8-bit raster encodings */
  612.  
  613. #undef Q
  614. #if    SEGMEM
  615.     UNSIGN32 *q[8];            /* pointers to 8 raster lines */
  616. #define Q(n) q[n]            /* use precomputed pointers */
  617. #else /* NOT SEGMEM */
  618. #define Q(n) (p - (n)*XBIT)        /* compute pointers on the fly */
  619. #endif /* SEGMEM */
  620.  
  621.     ytop = YBIT - 1;
  622.  
  623.     k = -1;                /* find bottom non-zero raster */
  624.     for (j = 0; (j < ytop) && (k < 0); ++j)    /* loop over raster lines */
  625.     {
  626.  
  627. #if    IBM_PC_MICROSOFT
  628.     for (k = XBIT - 1; ((k >= 0) && (*BITMAP(j, k) == 0)); --k)
  629.         ;                /* trim white space */
  630. #else /* NOT IBM_PC_MICROSOFT */
  631.     p = BITMAP(j, XBIT - 1);
  632.     for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
  633.         --p;            /* trim white space */
  634. #endif /* IBM_PC_MICROSOFT */
  635.  
  636.     }                    /* end loop over j */
  637.     ybottom = (j / 8) * 8 + 7;
  638.  
  639.     OUTF("\0333%c", 24);        /* 24/216 inch paperfeeding */
  640.  
  641.     for (j = ytop; (j >= ybottom); j -= 8)    /* loop over raster lines */
  642.     {                    /* in groups of 8 */
  643.  
  644. #if    SEGMEM
  645. #else /* NOT SEGMEM */
  646.     p = BITMAP(j, 0);        /* the j-th raster line */
  647. #endif /* SEGMEM */
  648.  
  649.     c = &v8[0];            /* vertical 8-bit encodings */
  650.     for (i = 0; i < XBIT; (++p, ++i))    /* loop over raster words */
  651.     {
  652.         /* PCC-20 compiled (1 << (HOST_WORD_SIZE-1)) to 0, so do it the
  653.         hard way, arghh... */
  654.         mask = 1;
  655.         mask <<= (HOST_WORD_SIZE - 1);    /* to select leftmost bit */
  656.  
  657. #if    SEGMEM
  658.         for (k = 0; k < 8; ++k)    /* compute pointers to 8 rasters */
  659.         q[k] = BITMAP(j - k, i);
  660. #endif /* SEGMEM */
  661.  
  662.         for (k = 0; k < HOST_WORD_SIZE; (++c, ++k))/* loop over word bits */
  663.         {
  664.         /* examine bits in 8 adjacent rows and build 8-bit */
  665.         /* character value */
  666.  
  667. #if    SEGMEM
  668.         *c = (BYTE) makechar(q, mask);
  669. #else /* NOT SEGMEM */
  670.         *c = (BYTE) makechar(&p, mask);
  671. #endif /* SEGMEM */
  672.  
  673.         mask >>= 1;        /* move masking bit right 1 position */
  674.         }                /* end loop over k */
  675.     }                /* end loop over i */
  676.     --c;                /* last character encoded */
  677.  
  678.     (void)outline((char *) &v8[0]);
  679.     }                    /* end loop over j */
  680.  
  681.     OUTS("\0332");            /* ESC 2 = normal paperfeeding */
  682.     OUTC('\f');                /* eject page with FF */
  683.  
  684.     (void)fflush(plotfp);
  685.     if (DISKFULL(plotfp))
  686.     (void)fatal("prtbmap(): Output error -- disk storage probably full");
  687. }
  688. #endif /* HIRES */
  689.  
  690. #include "prtpage.h"
  691. #include "readfont.h"
  692. #include "readgf.h"
  693. #include "readpk.h"
  694. #include "readpost.h"
  695. #include "readpxl.h"
  696. #include "reldfont.h"
  697. #include "rulepxl.h"
  698. #include "setchar.h"
  699. #include "setfntnm.h"
  700. #include "setrule.h"
  701. #include "signex.h"
  702. #include "skgfspec.h"
  703. #include "skipfont.h"
  704. #include "skpkspec.h"
  705. #include "special.h"
  706. #include "strchr.h"
  707. #include "strcm2.h"
  708. #include "strid2.h"
  709. #include "strrchr.h"
  710. #include "tctos.h"
  711. #include "usage.h"
  712. #include "warning.h"
  713.