home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_1.3 / Read-Me1.3 / Printer1.3 / Driver.Examples / src / epsonQ / render.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-01  |  6.8 KB  |  251 lines

  1. /*
  2.     EpsonQ (LQ-800/LQ-850/LQ-1000/LQ-1050/LQ-1500/LQ-2500) driver.
  3.     (tested on a Star NB24-15 (bw) and an Epson LQ-2500 (color) printer).
  4.     David Berezowski - October/87.
  5. */
  6.  
  7. #include <exec/types.h>
  8. #include <exec/nodes.h>
  9. #include <exec/lists.h>
  10. #include <exec/memory.h>
  11. #include "../printer/printer.h"
  12. #include "../printer/prtbase.h"
  13. #include "../printer/prtgfx.h"
  14.  
  15. #define NUMSTARTCMD    8    /* # of cmd bytes before binary data */
  16. #define NUMENDCMD    1    /* # of cmd bytes after binary data */
  17. #define NUMTOTALCMD (NUMSTARTCMD + NUMENDCMD)    /* total of above */
  18. #define NUMLFCMD    4    /* # of cmd bytes for linefeed */
  19. #define MAXCOLORBUFS    4    /* max # of color buffers */
  20.  
  21. #define STARTLEN    16
  22. #define PITCH        1
  23. #define CONDENSED    2
  24. #define LMARG        8
  25. #define RMARG        11
  26. #define DIREC        15
  27.  
  28. Render(ct, x, y, status)
  29. long ct, x, y, status;
  30. {
  31.     extern void *AllocMem(), FreeMem();
  32.  
  33.     extern struct PrinterData *PD;
  34.     extern struct PrinterExtendedData *PED;
  35.  
  36.     static UWORD RowSize, ColorSize, BufSize, TotalBufSize;
  37.     static UWORD dataoffset, dpi_code;
  38.     static UWORD colors[MAXCOLORBUFS]; /* color ptrs */
  39.     static UWORD colorcodes[MAXCOLORBUFS]; /* printer color codes */
  40.     static UWORD NumColorBufs; /* actually number of color buffers req. */
  41.     /*
  42.         00-01    \003P        set pitch (10 or 12 cpi)
  43.         02-02    \022        set condensed fine (on or off)
  44.         03-05    \033W\000    enlarge off
  45.         06-08    \033ln        set left margin to n
  46.         09-11    \033Qn        set right margin to n
  47.         12-12    \015        carriage return
  48.         13-15    \033U1        set uni-directional mode
  49.     */
  50.     static UBYTE StartBuf[STARTLEN] =
  51.         "\033P\022\033W\000\033ln\033Qn\015\033U1";
  52.     UBYTE *ptr, *ptrstart, *ptr2, *ptr2start;
  53.     int i, err;
  54.  
  55.     switch(status) {
  56.         case 0:  /* Master Initialization */
  57.             /*
  58.                 ct    - pointer to IODRPReq structure.
  59.                 x    - width of printed picture in pixels.
  60.                 y    - height of printed picture in pixels.
  61.             */
  62.             RowSize = x * 3;
  63.             ColorSize = RowSize + NUMTOTALCMD;
  64.             if (PD->pd_Preferences.PrintShade == SHADE_COLOR) {
  65.                 NumColorBufs = MAXCOLORBUFS;
  66.                 colors[0] = ColorSize * 3; /* Black */
  67.                 colors[1] = ColorSize * 0; /* Yellow */
  68.                 colors[2] = ColorSize * 1; /* Magenta */
  69.                 colors[3] = ColorSize * 2; /* Cyan */
  70.                 colorcodes[0] = 4; /* Yellow */
  71.                 colorcodes[1] = 1; /* Magenta */
  72.                 colorcodes[2] = 2; /* Cyan */
  73.                 colorcodes[3] = 0; /* Black */
  74.             }
  75.             else { /* grey-scale or black&white */
  76.                 NumColorBufs = 1;
  77.                 colors[0] = ColorSize * 0; /* Black */
  78.                 colorcodes[0] = 0; /* Black */
  79.             }
  80.             BufSize = ColorSize * NumColorBufs + NUMLFCMD;
  81.             TotalBufSize = BufSize * 2;
  82.             PD->pd_PrintBuf = AllocMem(TotalBufSize, MEMF_PUBLIC);
  83.             if (PD->pd_PrintBuf == NULL) {
  84.                 err = PDERR_BUFFERMEMORY; /* no mem */
  85.             }
  86.             else {
  87.                 dataoffset = NUMSTARTCMD;
  88.                 /*
  89.                     This printer prints graphics within its
  90.                     text margins.  This code makes sure the
  91.                     printer is in 10 cpi and then sets the
  92.                     left and right margins to their minimum
  93.                     and maximum values (respectively).  A
  94.                     carriage return is sent so that the
  95.                     print head is at the leftmost position
  96.                     as this printer starts printing from
  97.                     the print head's position.  The printer
  98.                     is put into unidirectional mode to
  99.                     reduce wavy vertical lines.
  100.                 */
  101.                 StartBuf[PITCH] = 'P'; /* 10 cpi */
  102.                 StartBuf[CONDENSED] = '\022'; /* off */
  103.                 /* left margin of 1 */
  104.                 StartBuf[LMARG] = 0;
  105.                 /* right margin of 80 or 136 */
  106.                 StartBuf[RMARG] = PD->pd_Preferences.
  107.                     PaperSize == W_TRACTOR ? 136 : 80;
  108.                 /* uni-directional mode */
  109.                 StartBuf[DIREC] = '1';
  110.                 err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  111.             }
  112.             break;
  113.  
  114.         case 1: /* Scale, Dither and Render */
  115.             /*
  116.                 ct    - pointer to PrtInfo structure.
  117.                 x    - 0.
  118.                 y    - row # (0 to Height - 1).
  119.             */
  120.             Transfer(ct, y, &PD->pd_PrintBuf[dataoffset], colors);
  121.             err = PDERR_NOERR; /* all ok */
  122.             break;
  123.  
  124.         case 2: /* Dump Buffer to Printer */
  125.             /*
  126.                 ct    - 0.
  127.                 x    - 0.
  128.                 y    - # of rows sent (1 to NumRows).
  129.             */
  130.             /* white-space strip */
  131.             ptrstart = &PD->pd_PrintBuf[dataoffset];
  132.             ptr2start = ptr2 = ptrstart - NUMSTARTCMD;
  133.             x = 0; /* flag no transfer required yet */
  134.             for (ct=0; ct<NumColorBufs;
  135.                 ct++, ptrstart += ColorSize) {
  136.                 i = RowSize;
  137.                 ptr = ptrstart + i - 1;
  138.                 while (i > 0 && *ptr == 0) {
  139.                     i--;
  140.                     ptr--;
  141.                 }
  142.                 if (i != 0) { /* if data */
  143.                     /* convert to # of pixels */
  144.                     i = (i + 2) / 3;
  145.                     ptr = ptrstart - NUMSTARTCMD;
  146.                     *ptr++ = 27;
  147.                     *ptr++ = 'r';
  148.                     *ptr++ = colorcodes[ct]; /* color */
  149.                     *ptr++ = 27;
  150.                     *ptr++ = '*';
  151.                     *ptr++ = dpi_code;    /* density */
  152.                     *ptr++ = i & 0xff;
  153.                     *ptr++ = i >> 8;    /* size */
  154.                     i *= 3; /* back to # of bytes used */
  155.                     *(ptrstart + i) = 13; /* cr */
  156.                     i += NUMTOTALCMD;
  157.                     /* if must transfer data */
  158.                     if (x != 0) {
  159.                         /* get src start */
  160.                         ptr = ptrstart - NUMSTARTCMD;
  161.                         /* xfer and update dest ptr */
  162.                         do {
  163.                             *ptr2++ = *ptr++;
  164.                         } while (--i);
  165.                     }
  166.                     else { /* no transfer required */
  167.                         /* update dest ptr */
  168.                         ptr2 += i;
  169.                     }
  170.                 }
  171.                 /* if compacted or 0 */
  172.                 if (i != RowSize + NUMTOTALCMD) {
  173.                     /* we need to transfer next time */
  174.                     x = 1;
  175.                 }
  176.             }
  177.             *ptr2++ = 13; /* cr */
  178.             *ptr2++ = 27;
  179.             *ptr2++ = 'J';
  180.             *ptr2++ = y; /* y/180 lf */
  181.             err = (*(PD->pd_PWrite))(ptr2start, ptr2 - ptr2start);
  182.             if (err == PDERR_NOERR) {
  183.                 dataoffset = (dataoffset == NUMSTARTCMD ?
  184.                     BufSize : 0) + NUMSTARTCMD;
  185.             }
  186.             break;
  187.  
  188.         case 3: /* Clear and Init Buffer */
  189.             /*
  190.                 ct    - 0.
  191.                 x    - 0.
  192.                 y    - 0.
  193.             */
  194.             ptr = &PD->pd_PrintBuf[dataoffset];
  195.             i = BufSize - NUMTOTALCMD - NUMLFCMD;
  196.             do {
  197.                 *ptr++ = 0;
  198.             } while (--i);
  199.             err = PDERR_NOERR; /* all ok */
  200.             break;
  201.  
  202.         case 4: /* Close Down */
  203.             /*
  204.                 ct    - error code.
  205.                 x    - io_Special flag from IODRPReq.
  206.                 y    - 0.
  207.             */
  208.             err = PDERR_NOERR; /* assume all ok */
  209.             /* if user did not cancel print */
  210.             if (ct != PDERR_CANCEL) {
  211.                 /* restore preferences pitch and margins */
  212.                 if (PD->pd_Preferences.PrintPitch == ELITE) {
  213.                     StartBuf[PITCH] = 'M'; /* 12 cpi */
  214.                 }
  215.                 else if (PD->pd_Preferences.PrintPitch == FINE) {
  216.                     StartBuf[CONDENSED] = '\017'; /* on */
  217.                 }
  218.                 StartBuf[LMARG] =
  219.                     PD->pd_Preferences.PrintLeftMargin - 1;
  220.                 StartBuf[RMARG] =
  221.                     PD->pd_Preferences.PrintRightMargin;
  222.                 StartBuf[DIREC] = '0'; /* bi-directional */
  223.                 err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  224.             }
  225.              /* wait for both buffers to empty */
  226.             (*(PD->pd_PBothReady))();
  227.             if (PD->pd_PrintBuf != NULL) {
  228.                 FreeMem(PD->pd_PrintBuf, TotalBufSize);
  229.             }
  230.             break;
  231.  
  232.         case 5:   /* Pre-Master Initialization */
  233.             /*
  234.                 ct    - 0 or pointer to IODRPReq structure.
  235.                 x    - io_Special flag from IODRPReq.
  236.                 y    - 0.
  237.             */
  238.             /*
  239.                 Kludge for weak power supplies.
  240.                 FANFOLD - use all 24 pins (default).
  241.                 SINGLE  - use only 16 pins.
  242.             */
  243.             PED->ped_NumRows = PD->pd_Preferences.PaperType ==
  244.                 SINGLE ? 16 : 24;
  245.             dpi_code = SetDensity(x & SPECIAL_DENSITYMASK);
  246.             err = PDERR_NOERR; /* all ok */
  247.             break;
  248.     }
  249.     return(err);
  250. }
  251.