gdevlbp8.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* Copyright (C) 1991, 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: gdevlbp8.c,v 1.3 2001/08/01 00:48:23 stefan911 Exp $*/
  16. /* Canon LBP-8II and LIPS III driver */
  17. #include "gdevprn.h"
  18. /*
  19. Modifications:
  20. 2.2.97 Lauri Paatero
  21. Changed CSI command into ESC [. DCS commands may still need to be changed
  22. (to ESC P).
  23. 4.9.96 Lauri Paatero
  24. Corrected LBP-8II margins again. Real problem was that (0,0) is NOT
  25. in upper left corner.
  26. Now using relative addressing for vertical addressing. This avoids
  27. problems
  28. when printing to paper with wrong size.
  29. 18.6.96 Lauri Paatero, lauri.paatero@paatero.pp.fi
  30. Corrected LBP-8II margins.
  31. Added logic to recognize (and optimize away) long strings of 00's in data.
  32. For LBP-8II removed use of 8-bit CSI (this does not work if 8-bit character
  33. set has been configured in LBP-8II. (Perhaps this should also be done
  34. for LBP-8III?)
  35. Original versions:
  36. LBP8 driver: Tom Quinn (trq@prg.oxford.ac.uk)
  37. LIPS III driver: Kenji Okamoto (okamoto@okamoto.cias.osakafu-u.ac.jp)
  38. */
  39. #define X_DPI 300
  40. #define Y_DPI 300
  41. #define LINE_SIZE ((X_DPI * 85 / 10 + 7) / 8) /* bytes per line */
  42. /* The device descriptors */
  43. private dev_proc_print_page(lbp8_print_page);
  44. private dev_proc_print_page(lips3_print_page);
  45. const gx_device_printer far_data gs_lbp8_device =
  46. prn_device(prn_std_procs, "lbp8",
  47. DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
  48. X_DPI, Y_DPI,
  49. 0.16, 0.2, 0.32, 0.21, /* margins: left, bottom, right, top */
  50. 1, lbp8_print_page);
  51. const gx_device_printer far_data gs_lips3_device =
  52. prn_device(prn_std_procs, "lips3",
  53. 82, /* width_10ths, 8.3" */
  54. 117, /* height_10ths, 11.7" */
  55. X_DPI, Y_DPI,
  56. 0.16, 0.27, 0.23, 0.27, /* margins */
  57. 1, lips3_print_page);
  58. /* ------ Internal routines ------ */
  59. #define ESC 0x1b
  60. #define CSI 0233
  61. #define DCS 0220
  62. #define ST 0234
  63. static const char lbp8_init[] = {
  64. ESC, ';', ESC, 'c', ESC, ';', /* reset, ISO */
  65. ESC, '[', '2', '&', 'z', /* fullpaint mode */
  66. ESC, '[', '1', '4', 'p', /* select page type (A4) */
  67. ESC, '[', '1', '1', 'h', /* set mode */
  68. ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
  69. ESC, '[', '6', '3', 'k', /* Move 63 dots up (to top of printable area) */
  70. };
  71. static const char *lbp8_end = NULL;
  72. static const char lips3_init[] = {
  73. ESC, '<', /* soft reset */
  74. DCS, '0', 'J', ST, /* JOB END */
  75. DCS, '3', '1', ';', '3', '0', '0', ';', '2', 'J', ST, /* 300dpi, LIPS3 JOB START */
  76. ESC, '<', /* soft reset */
  77. DCS, '2', 'y', 'P', 'r', 'i', 'n', 't', 'i', 'n', 'g', '(', 'g', 's', ')', ST, /* Printing (gs) display */
  78. ESC, '[', '?', '1', 'l', /* auto cr-lf disable */
  79. ESC, '[', '?', '2', 'h', /* auto ff disable */
  80. ESC, '[', '1', '1', 'h', /* set mode */
  81. ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
  82. ESC, '[', 'f' /* move to home position */
  83. };
  84. static const char lips3_end[] = {
  85. DCS, '0', 'J', ST /* JOB END */
  86. };
  87. /* Send the page to the printer. */
  88. private int
  89. can_print_page(gx_device_printer *pdev, FILE *prn_stream,
  90. const char *init, int init_size, const char *end, int end_size)
  91. {
  92. char data[LINE_SIZE*2];
  93. char *out_data;
  94. int last_line_nro = 0;
  95. fwrite(init, init_size, 1, prn_stream); /* initialize */
  96. /* Send each scan line in turn */
  97. {
  98. int lnum;
  99. int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
  100. byte rmask = (byte)(0xff << (-pdev->width & 7));
  101. for ( lnum = 0; lnum < pdev->height; lnum++ ) {
  102. char *end_data = data + LINE_SIZE;
  103. gdev_prn_copy_scan_lines(pdev, lnum,
  104. (byte *)data, line_size);
  105. /* Mask off 1-bits beyond the line width. */
  106. end_data[-1] &= rmask;
  107. /* Remove trailing 0s. */
  108. while ( end_data > data && end_data[-1] == 0 )
  109. end_data--;
  110. if ( end_data != data ) {
  111. int num_cols = 0;
  112. int out_count;
  113. int zero_count;
  114. out_data = data;
  115. /* move down */
  116. fprintf(prn_stream, "%c[%de",
  117. ESC, lnum-last_line_nro );
  118. last_line_nro = lnum;
  119. while (out_data < end_data) {
  120. /* Remove leading 0s*/
  121. while(out_data < end_data && *out_data == 0) {
  122. num_cols += 8;
  123. out_data++;
  124. }
  125. out_count = end_data - out_data;
  126. zero_count = 0;
  127. /* if there is a lot data, find if there is sequence of zeros */
  128. if (out_count>22) {
  129. out_count = 1;
  130. while(out_data+out_count+zero_count < end_data) {
  131. if (out_data[zero_count+out_count] != 0) {
  132. out_count += 1+zero_count;
  133. zero_count = 0;
  134. }
  135. else {
  136. zero_count++;
  137. if (zero_count>20)
  138. break;
  139. }
  140. }
  141. }
  142. if (out_count==0)
  143. break;
  144. /* move down and across*/
  145. fprintf(prn_stream, "%c[%d`",
  146. ESC, num_cols );
  147. /* transfer raster graphic command */
  148. fprintf(prn_stream, "%c[%d;%d;300;.r",
  149. ESC, out_count, out_count);
  150. /* send the row */
  151. fwrite(out_data, sizeof(char),
  152. out_count, prn_stream);
  153. out_data += out_count+zero_count;
  154. num_cols += 8*(out_count+zero_count);
  155. }
  156. }
  157. }
  158. }
  159. /* eject page */
  160. fprintf(prn_stream, "%c=", ESC);
  161. /* terminate */
  162. if (end != NULL)
  163. fwrite(end, end_size, 1, prn_stream);
  164. return 0;
  165. }
  166. /* Print an LBP-8 page. */
  167. private int
  168. lbp8_print_page(gx_device_printer *pdev, FILE *prn_stream)
  169. { return can_print_page(pdev, prn_stream, lbp8_init, sizeof(lbp8_init),
  170. lbp8_end, sizeof(lbp8_end));
  171. }
  172. /* Print a LIPS III page. */
  173. private int
  174. lips3_print_page(gx_device_printer *pdev, FILE *prn_stream)
  175. { return can_print_page(pdev, prn_stream, lips3_init, sizeof(lips3_init),
  176. lips3_end, sizeof(lips3_end));
  177. }