home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / maths / plplot / plplot_2 / drivers / ljiip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-19  |  10.9 KB  |  447 lines

  1. /* $Id: ljiip.c,v 1.4 1994/07/19 22:30:21 mjl Exp $
  2.  * $Log: ljiip.c,v $
  3.  * Revision 1.4  1994/07/19  22:30:21  mjl
  4.  * All device drivers: enabling macro renamed to PLD_<driver>, where <driver>
  5.  * is xwin, ps, etc.  See plDevs.h for more detail.
  6.  *
  7.  * Revision 1.3  1994/04/30  16:14:45  mjl
  8.  * Fixed format field (%ld instead of %d) or introduced casts where
  9.  * appropriate to eliminate warnings given by gcc -Wall.
  10.  *
  11.  * Revision 1.2  1994/04/09  03:10:43  furnish
  12.  * Teeny typo correction to remove duplicate symbols which caused HP to
  13.  * be unable to produce shared lib.
  14.  *
  15.  * Revision 1.1  1994/04/08  11:46:44  mjl
  16.  * New LaserJet IIp driver by Wesley Ebisuzaki, based on old ljii driver.
  17.  * Has compression and other optimizations.
  18. */
  19.  
  20. /*    ljiip.c
  21.  
  22.     PLPLOT Laser Jet IIp device driver.
  23.     Based on old LJII driver, modifications by Wesley Ebisuzaki
  24.  
  25.     DPI = 300, 150, 100    (dots per inch)
  26.         default: Amiga/Unix 300 dpi, MS-DOS 150 dpi
  27.         higher = better output, more memory, longer to print
  28.     GCMODE = 0, 2 (graphics compression mode)
  29.         default: 2,  old laser jets should use 0
  30.         compression can speed up the printing up to 3x
  31.  
  32. */
  33. #include "plDevs.h"
  34.  
  35. #ifdef PLD_ljii
  36.  
  37. #include "plplotP.h"
  38. #include "drivers.h"
  39. #include <math.h>
  40. #include <string.h>
  41.  
  42. #ifdef __GO32__            /* dos386/djgpp */
  43. #ifdef MSDOS
  44. #undef MSDOS
  45. #endif
  46. #endif
  47.  
  48. /* Function prototypes */
  49.  
  50. static void setpoint(PLINT, PLINT);
  51.  
  52. /* top level declarations */
  53.  
  54. /* GCMODE = graphics compression mode, 0=old laser jets, 2=ljiip or later */
  55. #define GCMODE   2
  56.  
  57. /* DPI = dots per inch, more dots=better plot, more memory, more time */
  58. /* possible DPI = 75, 100, 150, 300 */
  59. /* if DPI=300 then your machine must have a free 1Mb block of memory */
  60.  
  61. #define DPI      300
  62.  
  63. #ifdef MSDOS
  64. #undef  DPI
  65. #define DPI      150
  66. #endif
  67.  
  68. #define CURX     ((long) (DPI / 5))
  69. #define CURY     ((long) (DPI / 7))
  70. #define XDOTS     (376 * (DPI / 50))    /* # dots across */
  71. #define YDOTS     (500 * (DPI / 50))    /* # dots down */
  72. #define JETX     (XDOTS-1)
  73. #define JETY     (YDOTS-1)
  74.  
  75.  
  76. #define BPROW     (XDOTS/8L)    /* # bytes across */
  77. #define MAX_WID     8        /* max pen width in pixels */
  78. #define BPROW1     (BPROW + (MAX_WID+7)/8)
  79. /* pen has width, make bitmap bigger */
  80. #define NBYTES     BPROW1*(YDOTS+MAX_WID)    /* total number of bytes */
  81.  
  82. /* Graphics control characters. */
  83.  
  84. #define ESC      0x1b
  85. #define FF       0x0c
  86.  
  87. static char mask[8] =
  88. {'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'};
  89.  
  90. #ifndef MSDOS
  91. #define _HUGE
  92. #else
  93. #define _HUGE _huge
  94. #endif
  95.  
  96. static unsigned char _HUGE *bitmap;    /* points to memory area NBYTES in size */
  97.  
  98. /*----------------------------------------------------------------------*\
  99. * plD_init_ljiip()
  100. *
  101. * Initialize device.
  102. \*----------------------------------------------------------------------*/
  103.  
  104. void
  105. plD_init_ljiip(PLStream *pls)
  106. {
  107.     PLDev *dev;
  108.  
  109.     pls->termin = 0;        /* not an interactive terminal */
  110.     pls->icol0 = 1;
  111.     pls->color = 0;
  112.     pls->width = DPI / 100;
  113.     pls->bytecnt = 0;
  114.     pls->page = 0;
  115.  
  116. /* Initialize family file info */
  117.  
  118.     plFamInit(pls);
  119.  
  120. /* Prompt for a file name if not already set */
  121.  
  122.     plOpenFile(pls);
  123.  
  124. /* Allocate and initialize device-specific data */
  125.  
  126.     dev = plAllocDev(pls);
  127.  
  128.     dev->xold = UNDEFINED;
  129.     dev->yold = UNDEFINED;
  130.     dev->xmin = 0;
  131.     dev->ymin = 0;
  132.  
  133.     /* number of pixels / mm */
  134.     plP_setpxl((PLFLT) (DPI/25.4), (PLFLT) (DPI/25.4));
  135.  
  136. /* Rotate by 90 degrees since portrait mode addressing is used */
  137.  
  138.     dev->xmin = 0;
  139.     dev->ymin = 0;
  140.     dev->xmax = JETY;
  141.     dev->ymax = JETX;
  142.     dev->xlen = dev->xmax - dev->xmin;
  143.     dev->ylen = dev->ymax - dev->ymin;
  144.  
  145.     plP_setphy(dev->xmin, dev->xmax, dev->ymin, dev->ymax);
  146.  
  147. /* Allocate storage for bit map matrix */
  148.  
  149. #ifdef MSDOS
  150.     if ((bitmap = (unsigned char _HUGE *) halloc((long) NBYTES, sizeof(char))) == NULL)
  151.     plexit("Out of memory in call to calloc");
  152. #else
  153.     if ((bitmap = (unsigned char *) calloc(NBYTES, sizeof(char))) == NULL)
  154.     plexit("Out of memory in call to calloc");
  155. #endif
  156.  
  157. /* Reset Printer */
  158.  
  159.     fprintf(pls->OutFile, "%cE", ESC);
  160. }
  161.  
  162. /*----------------------------------------------------------------------*\
  163. * plD_line_ljiip()
  164. *
  165. * Draw a line in the current color from (x1,y1) to (x2,y2).
  166. \*----------------------------------------------------------------------*/
  167.  
  168. void
  169. plD_line_ljiip(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
  170. {
  171.     PLDev *dev = (PLDev *) pls->dev;
  172.     int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
  173.     int abs_dx, abs_dy, dx, dy, incx, incy;
  174.     int i, width, residual;
  175.     PLINT j;
  176.     width = pls->width;
  177.  
  178.     if (width > MAX_WID) width = MAX_WID;
  179.  
  180. /* Take mirror image, since PCL expects (0,0) to be at top left */
  181.  
  182.     y1 = dev->ymax - (y1 - dev->ymin);
  183.     y2 = dev->ymax - (y2 - dev->ymin);
  184.  
  185. /* Rotate by 90 degrees */
  186.  
  187.     plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1);
  188.     plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2);
  189.  
  190.     dx = x2 - x1;
  191.     dy = y2 - y1;
  192.  
  193.     if (dx < 0) {
  194.     abs_dx = -dx;
  195.     incx = -1;
  196.     }
  197.     else {
  198.     abs_dx = dx;
  199.     incx = 1;
  200.     }
  201.     if (dy < 0) {
  202.     abs_dy = -dy;
  203.     incy = -1;
  204.     }
  205.     else {
  206.     abs_dy = dy;
  207.     incy = 1;
  208.     }
  209.     if (width > 1) {
  210.     for (i = 0; i < width; i++) {
  211.         for (j = 0; j < width; j++) {
  212.             setpoint((PLINT) (x1+i), (PLINT) (y1+j));
  213.             setpoint((PLINT) (x2+i), (PLINT) (y2+j));
  214.         }
  215.     }
  216.     }
  217.     if (abs_dx >= abs_dy) {
  218.     residual = -(abs_dx >> 1);
  219.     if (width == 1) {
  220.             for (i = 0; i <= abs_dx; i++, x1 += incx) {
  221.                 setpoint((PLINT) (x1), (PLINT) (y1));
  222.                 if ((residual += abs_dy) >= 0) {
  223.                     residual -= abs_dx;
  224.                     y1 += incy;
  225.                 }
  226.             }
  227.     }
  228.     else {
  229.         for (i = 0; i <= abs_dx; i++, x1 += incx) {
  230.            for (j = 0; j < width; j++) {
  231.                setpoint((PLINT) (x1), (PLINT) (y1+j));
  232.                setpoint((PLINT) (x1+width-1), (PLINT) (y1+j));
  233.            }
  234.            if ((residual += abs_dy) >= 0) {
  235.            residual -= abs_dx;
  236.            y1 += incy;
  237.            }
  238.         }
  239.     }
  240.     }
  241.     else {
  242.     residual = -(abs_dy >> 1);
  243.         if (width == 1) {
  244.             for (i = 0; i <= abs_dy; i++, y1 += incy) {
  245.                 setpoint((PLINT) (x1), (PLINT) (y1));
  246.                 if ((residual += abs_dx) >= 0) {
  247.                     residual -= abs_dy;
  248.                     x1 += incx;
  249.                 }
  250.             }
  251.         }
  252.         else {
  253.             for (i = 0; i <= abs_dy; i++, y1 += incy) {
  254.                for (j = 0; j < width; j++) {
  255.                    setpoint((PLINT) (x1+j), (PLINT) (y1));
  256.                    setpoint((PLINT) (x1+j), (PLINT) (y1+width-1));
  257.                }
  258.                if ((residual += abs_dx) >= 0) {
  259.                    residual -= abs_dy;
  260.                    x1 += incx;
  261.                }
  262.             }
  263.         }
  264.     }
  265. }
  266.  
  267. /*----------------------------------------------------------------------*\
  268. * plD_polyline_ljiip()
  269. *
  270. * Draw a polyline in the current color.
  271. \*----------------------------------------------------------------------*/
  272.  
  273. void
  274. plD_polyline_ljiip(PLStream *pls, short *xa, short *ya, PLINT npts)
  275. {
  276.     PLINT i;
  277.  
  278.     for (i = 0; i < npts - 1; i++)
  279.     plD_line_ljiip(pls, xa[i], ya[i], xa[i + 1], ya[i + 1]);
  280. }
  281.  
  282. /*----------------------------------------------------------------------*\
  283. * plD_eop_ljiip()
  284. *
  285. * End of page.(prints it here).
  286. \*----------------------------------------------------------------------*/
  287.  
  288. void
  289. plD_eop_ljiip(PLStream *pls)
  290. {
  291.     PLINT j;
  292.     unsigned char _HUGE *p;
  293. #if GCMODE > 0
  294.     int i, iy, last, n, jmax;
  295.     unsigned char _HUGE t_buf[BPROW*2];
  296.     unsigned char c;
  297. #endif
  298.  
  299.     /* PCL III setup: ref. Deskjet Plus Printer Owner's Manual */
  300.  
  301.     fprintf(pls->OutFile,"\033*rB");          /* end raster graphics */
  302.     fprintf(pls->OutFile,"\033*t%3dR", DPI);    /* set DPI */
  303.  
  304. #if GCMODE != 0
  305.     fprintf(pls->OutFile,"\033*r%dS", XDOTS);    /* raster width */
  306.     fprintf(pls->OutFile,"\033*b%1dM", GCMODE); /* graphics mode */
  307. #endif
  308.  
  309.     /* First move cursor to origin */
  310.  
  311.     fprintf(pls->OutFile,"\033*p%ldX", CURX);
  312.     fprintf(pls->OutFile,"\033*p%ldY", CURY);
  313.     fprintf(pls->OutFile,"\033*r0A");        /* start graphics */
  314.  
  315.     /* Write out raster data */
  316.  
  317. #if GCMODE == 0
  318.     for (j = 0, p = bitmap; j < YDOTS; j++, p += BPROW1) {
  319.     fprintf(pls->OutFile,"\033*b>%dW", BPROW);
  320.     fwrite(p, BPROW, sizeof(char), pls->OutFile);
  321.     }
  322. #endif
  323. #if GCMODE == 2
  324.     for (iy = 0, p = bitmap; iy < YDOTS; iy++, p += BPROW1) {
  325.  
  326.     /* find last non-zero byte */
  327.     last = BPROW - 1;
  328.     while (last > 0 && p[last] == 0) last--;
  329.     last++;
  330.  
  331.     /* translate to mode 2, save results in t_buf[] */
  332.     i = n = 0;
  333.     while (i < last) {
  334.         c = p[i];
  335.         jmax = i + 127;
  336.         jmax = last < jmax ? last : jmax;
  337.         if (i < last - 2 && (c == p[i+1]) && (c == p[i+2])) {
  338.         j = i + 3;
  339.         while (j < jmax && c == p[j]) j++;
  340.         t_buf[n++] = (i-j+1) & 0xff;
  341.         t_buf[n++] = c;
  342.         i = j;
  343.         }
  344.         else {
  345.         for (j = i + 1; j < jmax; j++) {
  346.             if (j < last - 2 && (p[j] == p[j+1]) &&
  347.             (p[j+1] == p[j+2]) ) break;
  348.         }
  349.         t_buf[n++] = j - i - 1;
  350.         while (i < j) {
  351.             t_buf[n++] = p[i++];
  352.         }
  353.         /* i = j; */
  354.         }
  355.     }
  356.     fprintf(pls->OutFile,"\033*b%dW", (int) n);
  357.     fwrite(t_buf, (int) n, sizeof(char), pls->OutFile);
  358.     }
  359. #endif
  360.  
  361.     pls->bytecnt += NBYTES;
  362.  
  363.     /* End raster graphics and send Form Feed */
  364.     fprintf(pls->OutFile, "\033*rB");
  365.     fprintf(pls->OutFile, "%c", FF);
  366.  
  367.     /* Finally, clear out bitmap storage area */
  368.     memset((void *) bitmap, '\0', NBYTES);
  369. }
  370.  
  371. /*----------------------------------------------------------------------*\
  372. * plD_bop_ljiip()
  373. *
  374. * Set up for the next page.
  375. * Advance to next family file if necessary (file output).
  376. \*----------------------------------------------------------------------*/
  377.  
  378. void
  379. plD_bop_ljiip(PLStream *pls)
  380. {
  381.     if (!pls->termin)
  382.     plGetFam(pls);
  383.  
  384.     pls->page++;
  385. }
  386.  
  387. /*----------------------------------------------------------------------*\
  388. * plD_tidy_ljiip()
  389. *
  390. * Close graphics file or otherwise clean up.
  391. \*----------------------------------------------------------------------*/
  392.  
  393. void
  394. plD_tidy_ljiip(PLStream *pls)
  395. {
  396. /* Reset Printer */
  397.  
  398.     fprintf(pls->OutFile, "%cE", ESC);
  399.     fclose(pls->OutFile);
  400.     free((char *) bitmap);
  401. }
  402.  
  403. /*----------------------------------------------------------------------*\
  404. * plD_state_ljiip()
  405. *
  406. * Handle change in PLStream state (color, pen width, fill attribute, etc).
  407. \*----------------------------------------------------------------------*/
  408.  
  409. void 
  410. plD_state_ljiip(PLStream *pls, PLINT op)
  411. {
  412. }
  413.  
  414. /*----------------------------------------------------------------------*\
  415. * plD_esc_ljiip()
  416. *
  417. * Escape function.
  418. \*----------------------------------------------------------------------*/
  419.  
  420. void
  421. plD_esc_ljiip(PLStream *pls, PLINT op, void *ptr)
  422. {
  423. }
  424.  
  425. /*----------------------------------------------------------------------*\
  426. * setpoint()
  427. *
  428. * Sets a bit in the bitmap.
  429. \*----------------------------------------------------------------------*/
  430.  
  431. static void
  432. setpoint(PLINT x, PLINT y)
  433. {
  434.     PLINT index;
  435.     index = x / 8 + y * BPROW1;
  436.     *(bitmap + index) = *(bitmap + index) | mask[x % 8];
  437. }
  438.  
  439. #else
  440. int 
  441. pldummy_ljiip()
  442. {
  443.     return 0;
  444. }
  445.  
  446. #endif                /* PLD_ljii */
  447.