home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / printer / dvi2pcl.lha / dopage.c < prev    next >
C/C++ Source or Header  |  1992-11-25  |  8KB  |  319 lines

  1. /* $Log:    dopage.c,v $
  2.  * Revision 0.8  92/11/23  19:46:41  19:46:41  bt (Bo Thide')
  3.  * Fixed resolution bug. Portable downloading. Added/changed options. PJXL color support
  4.  * 
  5.  * Revision 0.7  92/11/13  02:41:25  02:41:25  bt (Bo Thide')
  6.  * More bug fixes and improvements. Support for PaintJet XL
  7.  * 
  8.  * Revision 0.6  92/11/10  21:47:41  21:47:41  bt (Bo Thide')
  9.  * Bug fixes. Added -R option. Better font handling.
  10.  * 
  11.  * Revision 0.5  92/11/09  16:25:28  16:25:28  bt (Bo Thide')
  12.  * Rewrite of dospecial.c. Extended \special support
  13.  * 
  14.  * Revision 0.4  92/11/08  02:45:44  02:45:44  bt (Bo Thide')
  15.  * Changed to portable bit manipulations. Replaced strrstr for non-POSIX compliant C. Fixed numerous bugs. Added support for more \special's.
  16.  * 
  17.  * Revision 0.3  92/08/24  12:45:36  12:45:36  bt (Bo Thide')
  18.  * Fixed 8 bit (dc font) support.
  19.  * 
  20.  * Revision 0.2  92/08/23  17:28:55  17:28:55  bt (Bo Thide')
  21.  * Source cleaned up.  Changed certain function calls.  Removed globals.
  22.  * 
  23.  * Revision 0.1  92/08/22  23:58:47  23:58:47  bt (Bo Thide')
  24.  * First Release.
  25.  *  */
  26.  
  27. /*
  28.  * This is the main printer dependent output routine, which is organized as
  29.  * a function with side effects. The subroutine is organized as a typical
  30.  * interpreter, with a multiway branch of the command code followed by 'goto'
  31.  * statements leading to branches that finish up the activities common to
  32.  * different commands.  dopage() aborts `dvi2pcl' if something unusual happens.
  33.  *
  34.  * The definition of dvi files refer to six registers, (h,v,w,x,y,z),  which
  35.  * hold integer values in dvi units. In practice, we also need registers hh
  36.  * and vv, the pixel analogs of h and v, since it is not always true that
  37.  * hh = pixel_round(h) or vv = pixel_round(v).
  38.  * The stack of (h,w,w,x,y,z) values is represented by eight arrays called
  39.  * hstack,...,zstack, hhstack and vvstack.
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include "dvi.h"
  44. #include "globals.h"
  45. #include "macros.h"
  46. #include "pcl.h"
  47.  
  48. static char rcsid[] = "$Header: dopage.c,v 0.8 92/11/23 19:46:41 bt Exp $";
  49.  
  50. dopage(bitfile, dvifile, pcllevel, resolution, device)
  51. FILE    *bitfile;
  52. FILE    *dvifile;
  53. short    pcllevel;
  54. short    resolution;
  55. short    device;
  56. {
  57.     unsigned char    o;
  58.     int        k;
  59.     int        hhh, vvv;
  60.     bool        badchar;
  61.     long        hh, vv;
  62.     long        p, q;
  63.     long        hstack[STACKSIZE], vstack[STACKSIZE], wstack[STACKSIZE];
  64.     long        xstack[STACKSIZE], ystack[STACKSIZE], zstack[STACKSIZE];
  65.     int        hhstack[STACKSIZE], vvstack[STACKSIZE];
  66.     charfmt        *c;
  67.  
  68.     h_posed = v_posed = FALSE;
  69.     s = hh = vv = h = v = w = x = y = z = 0;
  70.     font = NULL;
  71.     while (TRUE) {
  72.         o = getubyte(dvifile);
  73.         if(o >= DVI_SET1)
  74.             p = firstpar(dvifile, o);
  75. #ifdef DEBUG
  76.         fprintf(stderr,"\ndopage: o = %d, p = %ld, hh = %ld", o, p, hh);
  77. #endif
  78.         if(o < DVI_SET1) { 
  79.             c = drawchar(bitfile, o, hh, vv, resolution, device);
  80.             q = c->tfm_width;
  81.             hh += c->pxl_width;
  82.             goto move_right;
  83.         } else
  84.             switch(o) { 
  85.             case DVI_SET1:
  86.             case DVI_SET2:
  87.             case DVI_SET3:
  88.             case DVI_SET4:
  89.                 c = drawchar(bitfile, p, hh, vv, resolution,
  90.                   device);
  91.                 q = c->tfm_width;
  92.                 hh += c->pxl_width;
  93.                 goto move_right;
  94.                 break;
  95.             case DVI_PUT1:
  96.             case DVI_PUT2:
  97.             case DVI_PUT3:
  98.             case DVI_PUT4:
  99.                 drawchar(bitfile, p, hh, vv, resolution,
  100.                   device);
  101.                 goto done;
  102.                 break;
  103.             case DVI_SET_RULE:
  104.                 q = (long)getsquad(dvifile);
  105.                 drawrule(bitfile, rulepixels(p, conv),
  106.                   rulepixels(q, conv), hh, vv);
  107.                 hh += rulepixels(q, conv);
  108.                 goto move_right;
  109.                 break;
  110.             case DVI_PUT_RULE:
  111.                 q = (long)getsquad(dvifile);
  112.                 drawrule(bitfile, rulepixels(p, conv),
  113.                   rulepixels(q, conv), hh, vv);
  114.                 goto done;
  115.                 break;
  116.             case DVI_NOP:
  117.                 goto done;
  118.                 break;
  119.             case DVI_BOP:
  120.                 fprintf(stderr,"\n'DVI_BOP' occurred before 'DVI_EOP'");
  121.                 goto endfalse;
  122.                 break;
  123.             case DVI_EOP:
  124.                 if(maxpages)
  125.                     putc('\014',bitfile);  /* Formfeed */
  126.                 if(s)
  127.                     fprintf(stderr,"\nStack not empty at end of page");
  128.                 return (TRUE);
  129.                 break;
  130.             case DVI_PUSH:
  131.                 if(s == maxssofar) { 
  132.                     maxssofar++;
  133.                     if(s ==    maxs)
  134.                         fprintf(stderr,"\nDeeper than claimed in postamble");
  135.                     if(s == STACKSIZE) { 
  136.                         fprintf(stderr,"\nStack capacity exceeded");
  137.                     goto endfalse;
  138.                     }
  139.                 }
  140.                 hstack[s] = h;
  141.                 vstack[s] = v;
  142.                 wstack[s] = w;
  143.                 xstack[s] = x;
  144.                 ystack[s] = y;
  145.                 zstack[s] = z;
  146.                 hhstack[s] = hh;
  147.                 vvstack[s] = vv;
  148.                 s++;
  149.                 goto done;
  150.                 break;
  151.             case DVI_POP:
  152.                 if(s) { 
  153.                     s--;
  154.                     if(hh != hhstack[s]) h_posed = FALSE;
  155.                     if(vv != vvstack[s]) v_posed = FALSE;
  156.                     h = hstack[s];
  157.                     v = vstack[s];
  158.                     w = wstack[s];
  159.                     x = xstack[s];
  160.                     y = ystack[s];
  161.                     z = zstack[s];
  162.                     hh = hhstack[s];
  163.                     vv = vvstack[s];
  164.                 }
  165.                 else
  166.                     fprintf(stderr,"\nIllegal at level zero");
  167.                 goto done;
  168.                 break;
  169.             case DVI_RIGHT1:
  170.             case DVI_RIGHT2:
  171.             case DVI_RIGHT3:
  172.             case DVI_RIGHT4:
  173.                 goto out_space;
  174.                 break;
  175.             case DVI_W0:
  176.             case DVI_W1:
  177.             case DVI_W2:
  178.             case DVI_W3:
  179.             case DVI_W4:
  180.                 w = p;
  181.                 goto out_space;
  182.                 break;
  183.             case DVI_X0:
  184.             case DVI_X1:
  185.             case DVI_X2:
  186.             case DVI_X3:
  187.             case DVI_X4:
  188.                 x = p;
  189.                 goto out_space;
  190.                 break;
  191.             case DVI_DOWN1:
  192.             case DVI_DOWN2:
  193.             case DVI_DOWN3:
  194.             case DVI_DOWN4:
  195.                 goto move_down;
  196.                 break;
  197.             case DVI_Y0:
  198.             case DVI_Y1:
  199.             case DVI_Y2:
  200.             case DVI_Y3:
  201.             case DVI_Y4:
  202.                 y = p;
  203.                 goto move_down;
  204.                 break;
  205.             case DVI_Z0:
  206.             case DVI_Z1:
  207.             case DVI_Z2:
  208.             case DVI_Z3:
  209.             case DVI_Z4:
  210.                 z = p;
  211.                 goto move_down;
  212.                 break;
  213.             case DVI_FNT_DEF1:
  214.             case DVI_FNT_DEF2:
  215.             case DVI_FNT_DEF3:
  216.             case DVI_FNT_DEF4:
  217.                 skipfontdef(dvifile);
  218.                 goto done;
  219.                 break;
  220.             case DVI_XXX1:
  221.             case DVI_XXX2:
  222.             case DVI_XXX3:
  223.             case DVI_XXX4:
  224.                 badchar = FALSE;
  225.                 if((long)nextnamesfree - (long)names + p > NAMESIZE )
  226.                     prerror("Out of string space during special\n");
  227.                 for(k = 0 ; k < (int)p ; k++) { 
  228.                     q = (long)getubyte(dvifile);
  229.                     if((q < ' ') || (q > '~'))
  230.                         badchar = TRUE;
  231.                     *(nextnamesfree + k) = (char)q;
  232.                 }
  233.                 *(nextnamesfree + p) = 0;
  234.                 if(badchar)
  235.                     fprintf(stderr,"\nNon-ASCII character in xxx command");
  236.                 dospecial(bitfile, PRESCAN_OFF, pcllevel, hh,
  237.                   vv, resolution);
  238.                 goto done;
  239.                 break;
  240.             case DVI_PRE:
  241.                 fprintf(stderr,"\nPreamble command within a page");
  242.                 goto endfalse;
  243.                 break;
  244.             case DVI_POST:
  245.             case DVI_POSTPOST:
  246.                 fprintf(stderr,"\nPostamble command within a page");
  247.                 goto endfalse;
  248.                 break;
  249.             case DVI_UNDEF0:
  250.             case DVI_UNDEF1:
  251.             case DVI_UNDEF2:
  252.             case DVI_UNDEF3:
  253.             case DVI_UNDEF4:
  254.             case DVI_UNDEF5:
  255.                 fprintf(stderr,"\nUndefined DVI command %d.",o);
  256.                 goto done;
  257.                 break;
  258.             default:
  259.                 font = fontptr[p];
  260.                 gfont = gfontptr[p];
  261.                 if(font->down > 0)
  262.                     fprintf(bitfile, PCL4_SELECT_FONT, font->down);
  263.                 goto done;
  264.                 break;
  265.             }
  266.     
  267. out_space:
  268.         if((font == NULL) || (p >= font->space) || (p <= -4*font->space))
  269.             hh = round(conv*(h+p));
  270.         else
  271.             hh += round(conv*p);
  272.         q = p;
  273.         h_posed = FALSE;
  274. move_right:
  275.         hhh = round(conv*(h+q));
  276.         if(abs(hhh - hh) > MAXDRIFT) { 
  277.             h_posed = FALSE;
  278.             hh = hhh > hh ? hhh - MAXDRIFT : hhh + MAXDRIFT;
  279.         }
  280.         h += q;
  281.         if((long)abs(h) > maxhsofar) { 
  282.             if(((long)abs(h) > maxh + 99) && verbose) { 
  283.                 fprintf(stderr,"\n|h| > %d\n", maxh);
  284.                 maxh = (long)abs(h);
  285.             }
  286.             maxhsofar = (long)abs(h);
  287.         }
  288.         goto done;
  289.  
  290. move_down:
  291.         if((font == NULL) || ((long)abs(p) >= 5*font->space))
  292.             vv = round(conv*(v+p));
  293.         else
  294.             vv += round(conv*p);
  295.         v_posed = FALSE;
  296.         if((v > 0) &&  (p > 0) && (v > INFINITY-p))
  297.             fprintf(stderr,"Arithmetic overflow.  Parameter changed from %d to %d.", p, p=INFINITY-v);
  298.         if((v < 0) && (p < 0) && (-v > INFINITY+p))
  299.             fprintf(stderr,"\ndopage: Arithmetic overflow.  Parameter changed from %d to %d.", p, p = -(INFINITY+v));
  300.         vvv = round(conv*(v+p));
  301.         if(abs(vvv - vv) > MAXDRIFT)
  302.             vv = vvv > vv ? vvv - MAXDRIFT : vvv + MAXDRIFT;
  303.         v += p;
  304.         if((long)abs(v) > maxvsofar) { 
  305.             if(((long)abs(v) > maxv + 99) && verbose) { 
  306.                 fprintf(stderr,"\n|v| > %d.",maxv);
  307.                 maxv = (long)abs(v);
  308.             }
  309.             maxvsofar = (long)abs(v);
  310.         }
  311.         goto done;
  312.  
  313. done:
  314.         ;
  315.     }
  316. endfalse: 
  317.     prerror("\n! Bad .pcl file: page ended unexpectedly !\n");
  318. }
  319.