home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / DOS_14 / GS252DVX.ZIP / GDEVNP6.C < prev    next >
C/C++ Source or Header  |  1992-09-03  |  8KB  |  231 lines

  1. /* Copyright (C) 1989, 1990, 1991, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gdevnp6.c */
  21. /* NEC p6+ dot-matrix printer driver for Ghostscript */
  22. #include "gdevprn.h"
  23. /************************************************
  24.  * This driver is only for the (360 * 360) dpi resolution.
  25.  * For all other resolutions of the NEC p6+ use the epson-driver.
  26.  * I do not know if this driver works correctly on a NEC p6 or a p60.
  27.  * Report me if it works even on a p6 and a p60, please. Also send me
  28.  * bug reports.
  29.  * Most of the code is from the epson-driver. I just changed it a little bit
  30.  * to print 360 dpi vertical. Also I deleted the 9-pin printer code that is
  31.  * of no use here.
  32.  *                                      Marcus Haebler, 10.08.92
  33.  * email: haebler@dmswwu1a.uni-muenster.de
  34.  ************************************************/
  35.  
  36. #ifndef X_DPI
  37. #  define X_DPI 360        /* pixels per inch */
  38. #endif
  39. #ifndef Y_DPI
  40. #  define Y_DPI 360        /* pixels per inch */
  41. #endif
  42.  
  43. /* The device descriptors */
  44. private dev_proc_print_page (necp6_print_page);
  45. gx_device_printer gs_necp6_device =
  46. prn_device (prn_std_procs, "necp6",
  47.         85,            /* width_10ths, 8.5" */
  48.         110,        /* height_10ths, 11" */
  49.         X_DPI, Y_DPI,
  50.         0, 0, 0.5, 0,    /* margins */
  51.         1, necp6_print_page);
  52.  
  53. /* ------ Internal routines ------ */
  54.  
  55. /* Forward references */
  56. private void necp6_output_run (P4 (byte *, int, FILE *, int));
  57.  
  58. /* Send the page to the printer. */
  59. private int
  60. necp6_print_page (gx_device_printer * pdev, FILE * prn_stream)
  61. {
  62.   int line_size = gdev_mem_bytes_per_scan_line ((gx_device *) pdev);
  63.   int in_size = line_size * 24;    /* we need 24 lines */
  64.   byte *in = (byte *) gs_malloc (in_size, 1, "necp6_print_page(in)");
  65.   int out_size = ((pdev->width + 7) & -8) * 3;
  66.   byte *out = (byte *) gs_malloc (out_size, 1, "necp6_print_page(out)");
  67.   int skip = 0, lnum = 0, pass;
  68.  
  69.   /* Check allocations */
  70.   if (in == 0 || out == 0)
  71.     {
  72.       if (in)
  73.     gs_free ((char *) in, in_size, 1, "necp6_print_page(in)");
  74.       if (out)
  75.     gs_free ((char *) out, out_size, 1, "necp6_print_page(out)");
  76.       return -1;
  77.     }
  78.  
  79.   /* Initialize the printer and reset the margins. */
  80.   fwrite ("\033@\033P\033l\000\r\033Q", 1, 10, prn_stream);
  81.   fputc ((int) (pdev->width / pdev->x_pixels_per_inch * 10) + 2,
  82.      prn_stream);
  83.  
  84.   /* Print lines of graphics */
  85.   while (lnum < pdev->height)
  86.     {
  87.       byte *inp = in;
  88.       byte *in_end = in + line_size;
  89.       byte *out_end = out;
  90.       byte *out_blk;
  91.       register byte *outp;
  92.       int lcnt, lcnt2, offset_;
  93.  
  94.       /* Copy 1 scan line and test for all zero. */
  95.       gdev_prn_copy_scan_lines (pdev, lnum, in, line_size);
  96.       if (in[0] == 0 &&
  97.       !memcmp ((char *) in, (char *) in + 1, line_size - 1)
  98.     )
  99.     {
  100.       lnum++;
  101.       skip++;
  102.       continue;
  103.     }
  104.  
  105.       /* Vertical tab to the appropriate position. */
  106.       while (skip > 255)
  107.     {
  108.       fprintf (prn_stream, "\0343\377\012");
  109.       skip -= 255;
  110.     }
  111.       if (skip)
  112.     fprintf (prn_stream, "\0343%c\012", skip);
  113.  
  114.       /* Copy the rest of the scan lines. */
  115.       for (offset_ = 0; offset_ <= 1; offset_++)
  116.     {
  117.       lcnt = 1;
  118.       for (lcnt2 = offset_; lcnt2 <= 45; lcnt2 += 2)
  119.         lcnt += gdev_prn_copy_scan_lines (pdev, lnum + 2 + lcnt2,
  120.                        in + line_size * (lcnt2 / 2 + 1),
  121.                           line_size);
  122.       if (lcnt < 24)
  123.         memset (in + lcnt * line_size, 0,
  124.             in_size - lcnt * line_size);
  125.  
  126.       /* We have to 'transpose' blocks of 8 pixels x 8 lines, */
  127.       /* because that's how the printer wants the data. */
  128.       /* And because we are in a 24-pin mode, we have to */
  129.       /* transpose groups of 3 lines at a time. */
  130.  
  131.       for (; inp < in_end; inp++, out_end += 24)
  132.         {
  133.           gdev_prn_transpose_8x8 (inp, line_size, out_end, 3);
  134.           gdev_prn_transpose_8x8 (inp + line_size * 8, line_size, out_end + 1, 3);
  135.           gdev_prn_transpose_8x8 (inp + line_size * 16, line_size, out_end + 2, 3);
  136.         }
  137.       /* Remove trailing 0s. */
  138.       while (out_end > out && out_end[-1] == 0 &&
  139.          out_end[-2] == 0 && out_end[-3] == 0
  140.         )
  141.         out_end -= 3;
  142.  
  143.       for (pass = 1; pass <= 2; pass++)
  144.         {
  145.           for (out_blk = outp = out; outp < out_end;)
  146.         {        /* Skip a run of leading 0s. */
  147.           /* At least 10 are needed to make tabbing worth it. */
  148.           /* We do everything by 3's because we have 24 pins */
  149.  
  150.           if (*outp == 0 && outp + 12 <= out_end &&
  151.               outp[1] == 0 && outp[2] == 0 &&
  152.               (outp[3] | outp[4] | outp[5]) == 0 &&
  153.               (outp[6] | outp[7] | outp[8]) == 0 &&
  154.               (outp[9] | outp[10] | outp[11]) == 0
  155.             )
  156.             {
  157.               byte *zp = outp;
  158.               int tpos;
  159.               byte *newp;
  160.               outp += 12;
  161.               while (outp + 3 <= out_end && *outp == 0 &&
  162.                  outp[1] == 0 && outp[2] == 0
  163.             )
  164.             outp += 3;
  165.               tpos = (outp - out) / 108;
  166.               newp = out + tpos * 108;
  167.               if (newp > zp + 10)
  168.             {    /* Output preceding bit data. */
  169.               if (zp > out_blk)    /* only false at */
  170.                 /* beginning of line */
  171.                 necp6_output_run (out_blk, (int) (zp - out_blk),
  172.                         prn_stream, pass);
  173.               /* Tab over to the appropriate position. */
  174.               fprintf (prn_stream, "\033D%c%c\t", tpos, 0);
  175.               out_blk = outp = newp;
  176.             }
  177.             }
  178.           else
  179.             outp += 3;
  180.         }
  181.           if (outp > out_blk)
  182.         necp6_output_run (out_blk, (int) (outp - out_blk),
  183.                 prn_stream, pass);
  184.  
  185.           fputc ('\r', prn_stream);
  186.         }
  187.       if (offset_ == 0)
  188.         {
  189.           fprintf (prn_stream, "\0343\001\012");    /* 1/360 inch */
  190.           gdev_prn_copy_scan_lines (pdev, (1 + lnum), in, line_size);
  191.           memset (in + line_size, 0, in_size - line_size);
  192.           inp = in;
  193.           in_end = in + line_size;
  194.           out_end = out;
  195.         }
  196.     }
  197.       skip = 47;
  198.       lnum += 48;
  199.     }
  200.  
  201.   /* Eject the page and reinitialize the printer */
  202.   fputs ("\f\033@", prn_stream);
  203.   fflush (prn_stream);
  204.  
  205.   gs_free ((char *) out, out_size, 1, "necp6_print_page(out)");
  206.   gs_free ((char *) in, in_size, 1, "necp6_print_page(in)");
  207.   return 0;
  208. }
  209.  
  210. /* Output a single graphics command. */
  211. /* pass=0 for all columns, 1 for even columns, 2 for odd columns. */
  212. private void
  213. necp6_output_run (byte * data, int count, FILE * prn_stream, int pass)
  214. {
  215.   int xcount = count / 3;
  216.   fprintf (prn_stream, "\033*\050%c%c", xcount & 0xff, xcount >> 8);
  217.   if (!pass)
  218.     fwrite (data, 1, count, prn_stream);
  219.   else
  220.     {                /* Only write every other column of 3 bytes. */
  221.       int which = pass;
  222.       byte *dp = data;
  223.       register int i, j;
  224.       for (i = 0; i < xcount; i++, which++)
  225.     for (j = 0; j < 3; j++, dp++)
  226.       {
  227.         putc (((which & 1) ? *dp : 0), prn_stream);
  228.       }
  229.     }
  230. }
  231.