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

  1. /* $Log:    dospecial.c,v $
  2.  * Revision 0.8  92/11/23  19:46:42  19:46:42  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:26  02:41:26  bt (Bo Thide')
  6.  * More bug fixes and improvements. Support for PaintJet XL
  7.  * 
  8.  * Revision 0.6  92/11/10  21:47:42  21:47:42  bt (Bo Thide')
  9.  * Bug fixes. Added -R option. Better font handling.
  10.  * 
  11.  * Revision 0.5  92/11/09  16:25:29  16:25:29  bt (Bo Thide')
  12.  * Rewrite of dospecial.c. Extended \special support
  13.  * 
  14.  * Revision 0.4  92/11/08  02:45:45  02:45:45  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:37  12:45:37  bt (Bo Thide')
  18.  * Fixed 8 bit (dc font) support.
  19.  * 
  20.  * Revision 0.2  92/08/23  17:28:56  17:28:56  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 procedure will handle any special commands that might appear.
  29.  * The following variants are handled:
  30.  *
  31.  * \special{command}
  32.  * \special{command(parameters)}
  33.  * \special{command=parameters}
  34.  * \special{command parameters}
  35.  * \special{command:parameters}
  36.  *
  37.  * The string contained in the special command is in the name array starting at
  38.  * 'nextnamesfree' and ending with a '\0'. Also, the 'prescan' boolean should
  39.  * be checked to see if this is the first or second time that this string was
  40.  * encountered.
  41.  *
  42.  * Copyright 1992 Bo Thide', Uppsala, Sweden <bt@irfu.se>.
  43.  */
  44.  
  45. #define S_LANDSCAPE    0    /* Original \special "landscape" */
  46. #define S_INCLUDE    1    /* Original \special "include()" */
  47. #define S_GRAFIX    2    /* Original \special "grafix()" */
  48. #define S_MOVE        3    /* Original \special "move()" */
  49. #define S_ESCAPESEQ    4     /* dvi \special "escapeseq ..." */
  50. #define S_RASTERFILE    5     /* dvi \special "rasterfile ..." */
  51. #define S_RAWSTRING    6     /* dvi \special "rawstring ..." */
  52. #define S_ORIENTATION    7    /* Gustaf Neumann's \special "orientation" */
  53. #define S_FILE        8    /* Gustaf Neumann's \special "file" */
  54. #define S_PS        9     /* PostScript \special's "ps:" */
  55. #define S_EM        10    /* 'emtex' \special's "em:" */
  56. #define S_PCL        11    /* PCL \special's "pcl:" */
  57. #define S_HPGL        12    /* PCL5 \special's "hpgl:" */
  58. #define S_PJXL        13    /* PaintJet XL \special "rawstring ..." */
  59. #define SPECIALS    14      /* Number of \special's supported */
  60. #define GRAFLIST    7    /* Number of graphics resolutions supported */
  61. #define COLORLIST    8    /* Number of PaintJet XL text colors */
  62.  
  63. #include <ctype.h>
  64. #include <stdio.h>
  65. #include "globals.h"
  66. #include "pcl.h"
  67.  
  68. static char rcsid[] = "$Header: dospecial.c,v 0.8 92/11/23 19:46:42 bt Exp $";
  69.  
  70. void dospecial(bitfile, prescan, pcllevel, hh, vv, resolution)
  71. FILE    *bitfile;
  72. bool    prescan;
  73. short    pcllevel;
  74. long    hh, vv;
  75. short    resolution;
  76. {
  77.  
  78.   /* The \special arguemnt keywords and their assocated delimiters */
  79.   static char *spclargv[SPECIALS][2] = {
  80.     "landscape", "",
  81.     "include", "(",
  82.     "grafix", "(",
  83.     "move",    "(",
  84.     "escapeseq", " ",
  85.     "rasterfile", " ",
  86.     "rawstring", " ",
  87.     "orientation", "=",
  88.     "file", "=",
  89.     "ps", ":",
  90.     "em", ":",
  91.     "pcl", ":",
  92.     "hpgl", ":",
  93.     "pjxl", ":"
  94.     };
  95.   static char *graflist[] = {"600","300","180","150","100","90","75"};
  96.   static char *colorlist[] = {"black","red","green","yellow","blue",
  97.                   "magenta","cyan","white"};
  98.   char    *bufptr;
  99.   char    *delimptr;        /* Pointer to the argument delimiter */
  100.   char    *iptr, *jptr;        /* Generic pointers */
  101.   char    c;
  102.   char    drawrow[8];
  103.   char    curname[NAMELENGTH];    /* Current name of generic file */
  104.   bool    relative;
  105.   short    angle=0;
  106.   short    planes=1;
  107.   int    i, j, k, l;
  108.   int    pxl_rows, row_bytes;
  109.   int    gflag;
  110.   int    ic;
  111.   long    hoffset, voffset;
  112.   FILE    *genfile;        /* Generic file pointer */
  113.  
  114.   bufptr = nextnamesfree;
  115.  
  116. #ifdef DEBUG
  117. fprintf(stderr,"\ndospecial: nextnamesfree = '%s'\n", nextnamesfree);
  118. fprintf(stderr,"dospecial: prescan = '%d'\n", prescan);
  119. fprintf(stderr,"dospecial: pcllevel = '%d'\n", pcllevel);
  120. #endif /* DEBUG */
  121.  
  122.   /* Process as long as the 'nextnamesfree' is not empty */
  123.   while(*bufptr){
  124.     while(isspace(*bufptr))    /* Skip over all leading white space */
  125.       bufptr++;
  126.     if(*bufptr){        /* Process only if it was not all white space */
  127.       iptr = jptr = bufptr;
  128.       while(isalpha(*jptr))    /* Move to the end of the first alpha string */
  129.         jptr++;
  130.  
  131.       /* See if the first alpha string is an OK keyword */
  132.       k = 0;
  133.       while(strncmp(bufptr,spclargv[k][0],strlen(spclargv[k][0])))
  134.     k++;            /* If the keyword is correct k points to it */
  135.  
  136.       /* Locate the correct delimiter associated with the keyword */
  137.       while(*jptr && (*jptr != *spclargv[k][1]))
  138.     jptr++;
  139.       delimptr = jptr;
  140.  
  141.       /*
  142.       * Bail out if no correct keyword  (k >= SPECIALS)
  143.       * or no correct delimiter (*jptr == NULL) was found
  144.       */
  145.       if(prescan && ((k >= SPECIALS) || !*jptr)) {
  146.           fprintf(stderr,"\ndospecial: \\special command not understood: %s\n",
  147.         nextnamesfree);
  148.       return;
  149.       }
  150.       /*
  151.       *  Here we know that the keyword is OK and that delimptr points to
  152.       *  the correct delimiter associated with that keyword.
  153.       */
  154.  
  155. #ifdef DEBUG
  156. fprintf(stderr,"\ndospecial: delimptr = '%s'\n", delimptr);
  157. #endif /* DEBUG */
  158.  
  159.       /* Move bufptr to point to the delimiter, after the first alpha string */
  160.       bufptr = delimptr;
  161.  
  162.       /* Make sure the delimiter '(' has a matching ')' */
  163.       if(*delimptr == '(') {
  164.     bufptr++;
  165.     while((*bufptr != ')') && *bufptr)
  166.       bufptr++;
  167.     if(*bufptr == '\0')
  168.       fprintf(stderr,"\ndospecial: Expected ) after parameter in \\special{%s}.\n", nextnamesfree);
  169.     else
  170.       bufptr++;
  171.       }
  172.       else {        /* Handle the other delimiters */
  173.       bufptr++;
  174.       while(*bufptr)
  175.     bufptr++;
  176.       }
  177.       /* Now bufptr points to the end of the nextnamesfree string */
  178.  
  179.  
  180.       /* Move jptr to point to after the (one byte) delimiter */
  181.       jptr = delimptr + 1;
  182.  
  183.       /* Parse the rest of the string for keyword entry spclargv[k][0] */
  184.       switch (k) {
  185.  
  186.       case S_LANDSCAPE:      /* Landscape mode */
  187.         if(prescan)
  188.           landscape = TRUE;
  189.         break;
  190.  
  191.       case S_INCLUDE:          /* include(filename) */
  192.         if(!prescan) {
  193.           iptr = curname;
  194.           while((*jptr != ' ') && (*jptr != ')') && *jptr)
  195.             *iptr++ = *jptr++;
  196.           *iptr = '\0';
  197.  
  198. #ifdef DEBUG
  199. fprintf(stderr,"\ndospecial: S_INCLUDE curname = %s\n", curname);
  200. #endif /* DEBUG */
  201.  
  202.       if((genfile = fopen(curname,"r")) == NULL) {
  203.         fprintf(stderr,"Cannot open the \\special{include()} file %s for input.\n", curname);
  204.         exit(-1);
  205.         }
  206.       /* Make the cursor position current and push it */
  207.       /*
  208.       fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  209.           fputs(PCL4_PUSH, bitfile);
  210.       */
  211.           while((ic = getc(genfile)) != EOF)
  212.             putc(ic, bitfile);
  213.       fclose(genfile);
  214.       /*
  215.           fputs(PCL4_POP, bitfile);
  216.       */
  217.         }
  218.         break;
  219.  
  220.       case S_MOVE:    /* move(h=..dim v=..dim) */
  221.         if(!prescan) {
  222.           hoffset = voffset = 0L;
  223.           relative = TRUE;
  224.           while(*jptr != ')'){
  225.             while(*jptr == ' ')
  226.               jptr++;
  227.         if(!(c = *jptr++));
  228.         if(*jptr == '=') jptr++;
  229.         switch(c)
  230.         {
  231.         case 'h':
  232.           hoffset = dim_to_dots(jptr, resolution);
  233.           break;
  234.         case 'v':
  235.           voffset = dim_to_dots(jptr, resolution);
  236.           break;
  237.         case 'a':
  238.           relative = FALSE;
  239.           break;
  240.         case 'r':
  241.           relative = TRUE;
  242.           break;
  243.         default:
  244.           fprintf(stderr,"\ndospecial: Invalid parameter in \\special{move}\n");
  245.           break;
  246.         }
  247.       while((*jptr != ' ') && (*jptr != ')') && *jptr)
  248.         jptr++;
  249.     }
  250.  
  251. #ifdef DEBUG
  252. fprintf(stderr,"\ndospecial: S_MOVE relative = %d, hoffset = %ld, voffset = %ld\n", relative, hoffset, voffset);
  253. #endif /* DEBUG */
  254.  
  255.     if(relative) {
  256.       if(hoffset) 
  257.         fprintf(bitfile, PCL4_MOVE_HREL, hoffset);
  258.       if(voffset)
  259.       fprintf(bitfile, PCL4_MOVE_VREL, voffset);
  260.     }
  261.     else {
  262.       if(hoffset)
  263.         fprintf(bitfile, PCL4_MOVE_H_POSITION, hoffset);
  264.       if(voffset)
  265.         fprintf(bitfile, PCL4_MOVE_V_POSITION, voffset);
  266.     }
  267.       }
  268.       break;
  269.  
  270.       case S_GRAFIX:        /* grafix(filename [resolution]) */
  271.         if(!prescan) {
  272.           iptr = curname;
  273.           while((*jptr != ' ') && (*jptr != ')') && *jptr)
  274.             *iptr++ = *jptr++;
  275.           *iptr = '\0';
  276.       if((genfile = fopen(curname,"r")) == NULL) {
  277.         fprintf(stderr,"Cannot open the \\special{grafix()} input file %s for input.\n", curname);
  278.         exit(-1);
  279.       }
  280.           while(*jptr == ' ') jptr++;
  281.           delimptr = jptr;
  282.           while((*jptr != ' ') && (*jptr != ')') && *jptr)
  283.             jptr++;
  284.           if(jptr != delimptr)
  285.           {
  286.             *jptr = '\0';
  287.             l = 0;
  288.             while(l < GRAFLIST)
  289.               if(!strcmp(delimptr, graflist[l]))
  290.                 break;
  291.               else l++;
  292.           }
  293.           else l = 2;
  294.           if(l == GRAFLIST)
  295.           {
  296.             fprintf(stderr,"\ndospecial: Invalid resolution in \\special{grafix}: %s.\n", delimptr);
  297.             l = 2;
  298.           }
  299.           if(l)
  300.             fprintf(bitfile, PCL4_GRAPHRES, graflist[l]);
  301.       /* Make the cursor position current and push it */
  302.       fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  303.           fputs(PCL4_PUSH, bitfile);
  304.           fputs(PCL4_START_RASTER, bitfile);
  305.           pxl_rows = (getc(genfile) << 8);
  306.           pxl_rows = pxl_rows + getc(genfile);
  307.           gflag = getc(genfile);
  308.           if(!gflag)
  309.             sprintf(drawrow, PCL4_DRAWROW, row_bytes = getc(genfile));
  310.           for(i = 0 ; i < pxl_rows ; i++) {
  311.             if(gflag)
  312.               fprintf(bitfile, PCL4_DRAWROW, row_bytes = getc(genfile));
  313.             else
  314.               fputs(drawrow, bitfile);
  315.             for(j = 0 ; j < row_bytes ; j++)
  316.               putc(getc(genfile), bitfile);
  317.           }
  318.       fclose(genfile);
  319.           fputs(PCL4_END_RASTER, bitfile);
  320.           if(l)
  321.             fprintf(bitfile, PCL4_GRAPHRES, graflist[0]);
  322.           fputs(PCL4_POP, bitfile);
  323.         }
  324.         break;
  325.  
  326.       case S_ORIENTATION:    /* PCL5 print orientation/direction */
  327.         if(!prescan) {
  328.       if(pcllevel < 5)
  329.         fprintf(stderr,"\ndospecial: Changing print direction via \\special not supported at PCL level %d.\n           Only at PCL level 5 (option -5).", pcllevel);
  330.       else {
  331.  
  332.         angle = (short)atoi(jptr);
  333.         if(angle==1)
  334.           angle=90;
  335.         else if(angle==2)
  336.           angle=180;
  337.         else if(angle==3)
  338.           angle=270;
  339.  
  340. #ifdef DEBUG
  341. fprintf(stderr,"\ndospecial: S_ORIENTATION angle = %d\n", angle);
  342. #endif /* DEBUG */
  343.  
  344.         /* Make the cursor position current */
  345.         /*
  346.         fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  347.         */
  348.         fprintf(bitfile, PCL5_PRINT_DIRECTION, angle);
  349.       }
  350.     }
  351.     break;
  352.  
  353.       case S_FILE:        /* Input file */
  354.         if(!prescan) {
  355.       iptr = curname;
  356.           while((*jptr != ' ') && *jptr)
  357.             *iptr++ = *jptr++;
  358.           *iptr = '\0';
  359.       if((genfile = fopen(curname,"r")) == NULL) {
  360.         fprintf(stderr,"Cannot open the \\special{input=} file %s for input.\n", curname);
  361.         exit(-1);
  362.       }
  363.       /* Make the cursor position current and push it */
  364.       fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  365.           fputs(PCL4_PUSH, bitfile);
  366.           while((ic = getc(genfile)) != EOF)
  367.             putc(ic, bitfile);
  368.       fclose(genfile);
  369.           fputs(PCL4_POP, bitfile);
  370.         }
  371.         break;
  372.  
  373.       case S_PCL:        /* PCL code */
  374.       case S_PS:        /* PostScript code */
  375.         if(!prescan) {
  376.       /* Make the cursor position current and push it */
  377.       fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  378.           fputs(PCL4_PUSH, bitfile);
  379.             while(*jptr)
  380.               putc(*jptr++, bitfile);
  381.           fputs(PCL4_POP, bitfile);
  382.         }  
  383.     break;
  384.  
  385.       case S_HPGL:        /* PCL5 HP-GL/2 code */
  386.         if(!prescan) {
  387.       if(pcllevel < 5)
  388.         fprintf(stderr,"\ndospecial: Using HP-GL/2 commands in \\special not supported at PCL level %d.\n           Only at PCL level 5 or higher (option -5).", pcllevel);
  389.       else {
  390.       /* Make the cursor position current and push it */
  391.       fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  392.           fputs(PCL4_PUSH, bitfile);
  393.       /* Enter HP-GL/2 mode. Pen to previous PCL pen position */
  394.       fputs(PCL5_HPGLMODE_PCLPEN, bitfile);
  395.       while(*jptr)
  396.         putc(*jptr++, bitfile);
  397.       /* Enter PCL mode. Pen to previous PCL pen position */
  398.       fputs(PCL5_PCLMODE_PCLPEN, bitfile);
  399.           fputs(PCL4_POP, bitfile);
  400.       }
  401.         }  
  402.     break;
  403.  
  404.       case S_RASTERFILE:    /* rasterfile ...*/
  405.         if(!prescan) {
  406.       iptr = curname;
  407.           while((*jptr != ' ') && *jptr)
  408.             *iptr++ = *jptr++;
  409.           *iptr = '\0';
  410.  
  411. #ifdef DEBUG
  412. fprintf(stderr,"\ndospecial: S_RASTERFILE curname = %s\n", curname);
  413. #endif /* DEBUG */
  414.  
  415.       if((genfile = fopen(curname,"r")) == NULL){
  416.         fprintf(stderr,"Cannot open the \\special{rasterfile} file %s for input.\n", curname);
  417.         exit(-1);
  418.         }
  419.       /* Make the cursor position current and push it */
  420.       fprintf(bitfile, PCL4_MOVE_POSITION, hh+h_offset, vv+v_offset);
  421.           fputs(PCL4_PUSH, bitfile);
  422.           while((ic = getc(genfile)) != EOF)
  423.             putc(ic, bitfile);
  424.       fclose(genfile);
  425.           fputs(PCL4_POP, bitfile);
  426.         }
  427.         break;
  428.  
  429.       case S_PJXL:
  430.         if(!prescan) {
  431.  
  432. #ifdef DEBUG
  433. fprintf(stderr,"\ndospecial: S_PJXL jptr = %s\n", jptr);
  434. #endif /* DEBUG */
  435.  
  436.           l = 0;
  437.           while(l < GRAFLIST) {
  438.             if(!strcmp(jptr, colorlist[l]))
  439.               break;
  440.             else
  441.           l++;
  442.           }
  443.           if(l == GRAFLIST) {
  444.             fprintf(stderr,"\ndospecial: Invalid color in \\special{pjxl:}: %s.\n", jptr);
  445.         l = 0;
  446.           }
  447.       fprintf(bitfile, PJXL_TEXT_COLOR, l);
  448.         }
  449.     break;
  450.  
  451.       case S_ESCAPESEQ:
  452.       case S_RAWSTRING:
  453.       case S_EM:
  454.         if(prescan) {
  455.           fprintf(stderr,"\ndospecial: \\special command not implemented: %s\n",
  456.         nextnamesfree);
  457.         }
  458.         break;
  459.       }
  460.     }
  461.   }
  462. }
  463.