home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 377b.lha / devices / printer / epsonx / render.c < prev    next >
Encoding:
C/C++ Source or Header  |  1980-02-03  |  9.7 KB  |  353 lines

  1. /* Copyright (c) 1990 Commodore-Amiga, Inc.
  2.  *
  3.  * This example is provided in electronic form by Commodore-Amiga, Inc. for
  4.  * use with the 1.3 revisions of the Addison-Wesley Amiga reference manuals. 
  5.  * The 1.3 Addison-Wesley Amiga Reference Manual series contains additional
  6.  * information on the correct usage of the techniques and operating system
  7.  * functions presented in this example.  The source and executable code of
  8.  * this example may only be distributed in free electronic form, via bulletin
  9.  * board or as part of a fully non-commercial and freely redistributable
  10.  * diskette.  Both the source and executable code (including comments) must
  11.  * be included, without modification, in any copy.  This example may not be
  12.  * published in printed form or distributed with any commercial product.
  13.  * However, the programming techniques and support routines set forth in
  14.  * this example may be used in the development of original executable
  15.  * software products for Commodore Amiga computers.
  16.  * All other rights reserved.
  17.  * This example is provided "as-is" and is subject to change; no warranties
  18.  * are made.  All use is at your own risk.  No liability or responsibility
  19.  * is assumed.
  20.  */
  21.  
  22. #include <exec/types.h>
  23. #include <exec/nodes.h>
  24. #include <exec/lists.h>
  25. #include <exec/memory.h>
  26.  
  27. #include <devices/printer.h>
  28. #include <devices/prtbase.h>
  29.  
  30. #define NUMSTARTCMD    7    /* # of cmd bytes before binary data */
  31. #define NUMENDCMD    1    /* # of cmd bytes after binary data */
  32. #define NUMTOTALCMD     (NUMSTARTCMD + NUMENDCMD)    /* total of above */
  33. #define NUMLFCMD    4    /* # of cmd bytes for linefeed */
  34. #define MAXCOLORBUFS    4    /* max # of color buffers */
  35.  
  36. #define STARTLEN    19
  37. #define PITCH        1
  38. #define CONDENSED    2
  39. #define LMARG        8
  40. #define RMARG        11
  41. #define DIREC        15
  42.  
  43. static ULONG TwoBufSize;
  44. static UWORD RowSize, ColorSize, NumColorBufs, dpi_code, spacing;
  45. static UWORD colorcodes[MAXCOLORBUFS];
  46.  
  47. void ClearAndInit(UBYTE *);
  48. UBYTE *CompactBuf(UBYTE *, UBYTE *, LONG, int);
  49.  
  50. int
  51. Render(ct, x, y, status)
  52. long ct, x, y, status;
  53. {
  54.     extern void *AllocMem(), FreeMem();
  55.  
  56.     extern struct PrinterData *PD;
  57.     extern struct PrinterExtendedData *PED;
  58.  
  59.     UBYTE *CompactBuf();
  60.     static ULONG BufSize, TotalBufSize,dataoffset;
  61.     static UWORD spacing, colors[MAXCOLORBUFS];
  62.     /*
  63.         00-01    \003P        set pitch (10 or 12 cpi)
  64.         02-02    \022        set condensed fine (on or off)
  65.         03-05    \033W\000    enlarge off
  66.         06-08    \033ln        set left margin to n
  67.         09-11    \033Qn        set right margin to n
  68.         12-12    \015        carriage return
  69.         13-15    \033U1        set uni-directional mode
  70.         16-18    \033t\000    see kludge note below
  71.         Kludge to get this to work on a CBM_MPS-1250  which interprets
  72.         'ESCr' as go into reverse print mode.  The 'ESCt' tells it to
  73.         get out of reverse print mode.  The 'NULL' is ignored by the
  74.         CBM_MPS-1250 and required by all Epson printers as the
  75.         terminator for the 'ESCtNULL' command which means select
  76.         normal char set (which has no effect).
  77.     */
  78.     static UBYTE StartBuf[STARTLEN] =
  79. {0x1b,'P',0x12,0x1b,'W',0x0,0x1b,'l','n',0x1b,'Q','n',0x0d,0x1b,'U',0x01,
  80.  0x1b,'t',0x0};
  81. /*        "\033P\022\033W\000\033ln\033Qn\015\033U1\033t\000"; */
  82.                
  83.     UBYTE *ptr, *ptrstart;
  84.     int err;
  85.  
  86.     switch(status) {
  87.         case 0 : /* Master Initialization */
  88.             /*
  89.                 ct    - pointer to IODRPReq structure.
  90.                 x    - width of printed picture in pixels.
  91.                 y    - height of printed picture in pixels.
  92.             */
  93.             RowSize = x;
  94.             ColorSize = RowSize + NUMTOTALCMD;
  95.             if (PD->pd_Preferences.PrintShade == SHADE_COLOR) {
  96.                 NumColorBufs = MAXCOLORBUFS;
  97.                 colors[0] = ColorSize * 3; /* Black */
  98.                 colors[1] = ColorSize * 0; /* Yellow */
  99.                 colors[2] = ColorSize * 1; /* Magenta */
  100.                 colors[3] = ColorSize * 2; /* Cyan */
  101.                 colorcodes[0] = 4; /* Yellow */
  102.                 colorcodes[1] = 1; /* Magenta */
  103.                 colorcodes[2] = 2; /* Cyan */
  104.                 colorcodes[3] = 0; /* Black */
  105.             }
  106.             else { /* grey-scale or black&white */
  107.                 NumColorBufs = 1;
  108.                 colors[0] = ColorSize * 0; /* Black */
  109.                 colorcodes[0] = 0; /* Black */
  110.             }
  111.             BufSize = ColorSize * NumColorBufs + NUMLFCMD;
  112.             if (PED->ped_YDotsInch == 216) {
  113.                 TwoBufSize = BufSize * 3;
  114.                 TotalBufSize = BufSize * 6;
  115.             }
  116.             else if (PED->ped_YDotsInch == 144) {
  117.                 TwoBufSize = BufSize * 2;
  118.                 TotalBufSize = BufSize * 4;
  119.             }
  120.             else {
  121.                 TwoBufSize = BufSize * 1;
  122.                 TotalBufSize = BufSize * 2;
  123.             }
  124.             PD->pd_PrintBuf = AllocMem(TotalBufSize, MEMF_PUBLIC);
  125.             if (PD->pd_PrintBuf == NULL) {
  126.                 err = PDERR_BUFFERMEMORY;
  127.             }
  128.             else {
  129.                 dataoffset = NUMSTARTCMD;
  130.                 /*
  131.                     This printer prints graphics within its
  132.                     text margins.  This code makes sure the
  133.                     printer is in 10 cpi and then sets the
  134.                     left and right margins to their minimum
  135.                     and maximum values (respectively).  A
  136.                     carriage return is sent so that the
  137.                     print head is at the leftmost position
  138.                     as this printer starts printing from
  139.                     the print head's position.  The printer
  140.                     is put into unidirectional mode to
  141.                     reduce wavy vertical lines.
  142.                 */
  143.                 StartBuf[PITCH] = 'P'; /* 10 cpi */
  144.                 StartBuf[CONDENSED] = '\022'; /* off */
  145.                 /* left margin of 1 */
  146.                 StartBuf[LMARG] = 0;
  147.                 /* right margin of 80 or 136 */
  148.                 StartBuf[RMARG] = PD->pd_Preferences.
  149.                     PaperSize == W_TRACTOR ? 136 : 80;
  150.                 /* uni-directional mode */
  151.                 StartBuf[DIREC] = '1';
  152.                 err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  153.             }
  154.             break;
  155.  
  156.         case 1 : /* Scale, Dither and Render */
  157.             /*
  158.                 ct    - pointer to PrtInfo structure.
  159.                 x    - 0.
  160.                 y    - row # (0 to Height - 1).
  161.             */
  162.             Transfer(ct, y, &PD->pd_PrintBuf[dataoffset], colors,
  163.                 BufSize);
  164.             err = PDERR_NOERR; /* all ok */
  165.             break;
  166.  
  167.         case 2 : /* Dump Buffer to Printer */
  168.             /*
  169.                 ct    - 0.
  170.                 x    - 0.
  171.                 y    - # of rows sent (1 to NumRows).
  172.  
  173.             */
  174.             /* white-space strip */
  175.             ptrstart = &PD->pd_PrintBuf[dataoffset - NUMSTARTCMD];
  176.             if (PED->ped_YDotsInch == 72) {
  177.                 /* y range : 1 to 8 */
  178.                 y = y * 3 - spacing;
  179.                 ptr = CompactBuf(ptrstart + NUMSTARTCMD,
  180.                     ptrstart, y, 1);
  181.             }
  182.             else if (PED->ped_YDotsInch == 144) {
  183.                 /* y range : 1 to 16 */
  184.                 ptr = CompactBuf(ptrstart + NUMSTARTCMD,
  185.                     ptrstart, 2, 1);
  186.                 if (y > 1) {
  187.                     ptr = CompactBuf(&PD->pd_PrintBuf[
  188.                         dataoffset + BufSize],
  189.                         ptr, y * 3 / 2 - 2, 0);
  190.                 }
  191.             }
  192.             else if (PED->ped_YDotsInch == 216) {
  193.                 /* y range : 1 to 24 */
  194.                 ptr = CompactBuf(ptrstart + NUMSTARTCMD,
  195.                     ptrstart, 1, 1);
  196.                 if (y > 1) {
  197.                     ptr = CompactBuf(&PD->pd_PrintBuf[
  198.                         dataoffset + BufSize],
  199.                         ptr, 1, 0);
  200.                 }
  201.                 if (y > 2) {
  202.                     ptr = CompactBuf(&PD->pd_PrintBuf[
  203.                         dataoffset + BufSize * 2],
  204.                         ptr, y - 2, 0);
  205.                 }
  206.             }
  207.             err = (*(PD->pd_PWrite))(ptrstart, ptr - ptrstart);
  208.             if (err == PDERR_NOERR) {
  209.                 dataoffset = (dataoffset == NUMSTARTCMD ?
  210.                     TwoBufSize : 0) + NUMSTARTCMD;
  211.             }
  212.             break;
  213.  
  214.         case 3 : /* Clear and Init Buffer */
  215.             /*
  216.                 ct    - 0.
  217.                 x    - 0.
  218.                 y    - 0.
  219.             */
  220.             ClearAndInit(&PD->pd_PrintBuf[dataoffset]);
  221.             err = PDERR_NOERR;
  222.             break;
  223.  
  224.         case 4 : /* Close Down */
  225.             /*
  226.                 ct    - error code.
  227.                 x    - io_Special flag from IODRPReq.
  228.                 y    - 0.
  229.             */
  230.             err = PDERR_NOERR; /* assume all ok */
  231.             /* if user did not cancel print */
  232.             if (ct != PDERR_CANCEL) {
  233.                 /* restore preferences pitch and margins */
  234.                 if (PD->pd_Preferences.PrintPitch == ELITE) {
  235.                     StartBuf[PITCH] = 'M'; /* 12 cpi */
  236.                 }
  237.                 else if (PD->pd_Preferences.PrintPitch == FINE) {
  238.                     StartBuf[CONDENSED] = '\017'; /* on */
  239.                 }
  240.                 StartBuf[LMARG] =
  241.                     PD->pd_Preferences.PrintLeftMargin - 1;
  242.                 StartBuf[RMARG] =
  243.                     PD->pd_Preferences.PrintRightMargin;
  244.                 StartBuf[DIREC] = '0'; /* bi-directional */
  245.                 err = (*(PD->pd_PWrite))(StartBuf, STARTLEN);
  246.             }
  247.             (*(PD->pd_PBothReady))();
  248.             if (PD->pd_PrintBuf != NULL) {
  249.                 FreeMem(PD->pd_PrintBuf, TotalBufSize);
  250.             }
  251.             break;
  252.  
  253.         case 5 :  /* Pre-Master Initialization */
  254.             /*
  255.                 ct    - 0 or pointer to IODRPReq structure.
  256.                 x    - io_Special flag from IODRPReq.
  257.                 y    - 0.
  258.             */
  259.             /* kludge for sloppy tractor mechanism */
  260.             spacing = PD->pd_Preferences.PaperType == SINGLE ?
  261.                 1 : 0;
  262.             dpi_code = SetDensity(x & SPECIAL_DENSITYMASK);
  263.             err = PDERR_NOERR;
  264.             break;
  265.     }
  266.     return(err);
  267. }
  268.  
  269. UBYTE *CompactBuf(ptrstart, ptr2start, y, flag)
  270. UBYTE *ptrstart, *ptr2start;
  271. long y;
  272. int flag; /* 0 - not first pass, !0 - first pass */
  273. {
  274.     static int x;
  275.     UBYTE *ptr, *ptr2;
  276.         UBYTE **dummy;
  277.  
  278.     long ct;
  279.     int i;
  280.  
  281.  
  282.     ptr2 = ptr2start; /* where to put the compacted data */
  283.     if (flag) {
  284.         x = 0; /* flag no transfer required yet */
  285.     }
  286.     for (ct=0; ct<NumColorBufs; ct++, ptrstart += ColorSize) {
  287.         i = RowSize;
  288.         ptr = ptrstart + i - 1;
  289.         while (i > 0 && *ptr == 0) {
  290.             i--;
  291.             ptr--;
  292.         }
  293.         if (i != 0) { /* if data */
  294.             *(++ptr) = 13;            /* <cr> */
  295.             ptr = ptrstart - NUMSTARTCMD;
  296.             *ptr++ = 27;
  297.             *ptr++ = 'r';
  298.             *ptr++ = colorcodes[ct];    /* color */
  299.             *ptr++ = 27;
  300.             *ptr++ = dpi_code;        /* density */
  301.             *ptr++ = i & 0xff;
  302.             *ptr++ = i >> 8;        /* size */
  303.             i += NUMTOTALCMD;
  304.             if (x != 0) { /* if must transfer data */
  305.                 /* get src start */
  306.                 ptr = ptrstart - NUMSTARTCMD;
  307.                 dummy = &ptr;  /* otherwise Lattice looses 
  308.                         track of the pointer..... */
  309.                 do { /* transfer and update dest ptr */
  310.                     *ptr2++ = *ptr++;
  311.                 } while (--i);
  312.             }
  313.             else { /* no transfer required */
  314.                 ptr2 += i; /* update dest ptr */
  315.             }
  316.         }
  317.         if (i != RowSize + NUMTOTALCMD) { /* if compacted or 0 */
  318.             x = 1; /* flag that we need to transfer next time */
  319.         }
  320.     }
  321.     *ptr2++ = 13; /* cr */
  322.     *ptr2++ = 27;
  323.     *ptr2++ = 'J';
  324.     *ptr2++ = y; /* y/216 lf */
  325.     return(ptr2);
  326. }
  327.  
  328.  
  329. void ClearAndInit(ptr)
  330. UBYTE *ptr;
  331. {
  332.     ULONG *lptr, i, j;
  333.  
  334.     /*
  335.         Note : Since 'NUMTOTALCMD + NUMLFCMD' is > 3 bytes it is safe
  336.         to do the following to speed things up.
  337.     */
  338.     i = TwoBufSize - NUMTOTALCMD - NUMLFCMD;
  339.     j = (ULONG)ptr;
  340.     if (!(j & 1)) { /* if on a word boundary, clear by longs */
  341.         i = (i + 3) / 4;
  342.         lptr = (ULONG *)ptr;
  343.         do {
  344.             *lptr++ = 0;
  345.         } while (--i);
  346.     }
  347.     else { /* clear by bytes */
  348.         do {
  349.             *ptr++ = 0;
  350.         } while (--i);
  351.     }
  352. }
  353.