1 /* Copyright (C) 1991, 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gdevlbp8.c,v 1.6 2002/10/07 08:28:56 ghostgum Exp $*/
18 /* Canon LBP-8II and LIPS III driver */
19 #include "gdevprn.h"
20
21 /*
22 Modifications:
23 2.2.97 Lauri Paatero
24 Changed CSI command into ESC [. DCS commands may still need to be changed
25 (to ESC P).
26 4.9.96 Lauri Paatero
27 Corrected LBP-8II margins again. Real problem was that (0,0) is NOT
28 in upper left corner.
29 Now using relative addressing for vertical addressing. This avoids
30 problems
31 when printing to paper with wrong size.
32 18.6.96 Lauri Paatero, lauri.paatero@paatero.pp.fi
33 Corrected LBP-8II margins.
34 Added logic to recognize (and optimize away) long strings of 00's in data.
35 For LBP-8II removed use of 8-bit CSI (this does not work if 8-bit character
36 set has been configured in LBP-8II. (Perhaps this should also be done
37 for LBP-8III?)
38 Original versions:
39 LBP8 driver: Tom Quinn (trq@prg.oxford.ac.uk)
40 LIPS III driver: Kenji Okamoto (okamoto@okamoto.cias.osakafu-u.ac.jp)
41 */
42
43
44 #define X_DPI 300
45 #define Y_DPI 300
46 #define LINE_SIZE ((X_DPI * 85 / 10 + 7) / 8) /* bytes per line */
47
48 /* The device descriptors */
49 private dev_proc_print_page(lbp8_print_page);
50 private dev_proc_print_page(lips3_print_page);
51
52 const gx_device_printer far_data gs_lbp8_device =
53 prn_device(prn_std_procs, "lbp8",
54 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
55 X_DPI, Y_DPI,
56 0.16, 0.2, 0.32, 0.21, /* margins: left, bottom, right, top */
57 1, lbp8_print_page);
58
59 const gx_device_printer far_data gs_lips3_device =
60 prn_device(prn_std_procs, "lips3",
61 82, /* width_10ths, 8.3" */
62 117, /* height_10ths, 11.7" */
63 X_DPI, Y_DPI,
64 0.16, 0.27, 0.23, 0.27, /* margins */
65 1, lips3_print_page);
66
67 /* ------ Internal routines ------ */
68
69 #define ESC (char)0x1b
70 #define CSI '\233'
71 #define DCS '\220'
72 #define ST '\234'
73
74 static const char lbp8_init[] = {
75 ESC, ';', ESC, 'c', ESC, ';', /* reset, ISO */
76 ESC, '[', '2', '&', 'z', /* fullpaint mode */
77 ESC, '[', '1', '4', 'p', /* select page type (A4) */
78 ESC, '[', '1', '1', 'h', /* set mode */
79 ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
80 ESC, '[', '6', '3', 'k', /* Move 63 dots up (to top of printable area) */
81 };
82
83 static const char *lbp8_end = NULL;
84
85 static const char lips3_init[] = {
86 ESC, '<', /* soft reset */
87 DCS, '0', 'J', ST, /* JOB END */
88 DCS, '3', '1', ';', '3', '0', '0', ';', '2', 'J', ST, /* 300dpi, LIPS3 JOB START */
89 ESC, '<', /* soft reset */
90 DCS, '2', 'y', 'P', 'r', 'i', 'n', 't', 'i', 'n', 'g', '(', 'g', 's', ')', ST, /* Printing (gs) display */
91 ESC, '[', '?', '1', 'l', /* auto cr-lf disable */
92 ESC, '[', '?', '2', 'h', /* auto ff disable */
93 ESC, '[', '1', '1', 'h', /* set mode */
94 ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
95 ESC, '[', 'f' /* move to home position */
96 };
97
98 static const char lips3_end[] = {
99 DCS, '0', 'J', ST /* JOB END */
100 };
101
102 /* Send the page to the printer. */
103 private int
can_print_page(gx_device_printer * pdev,FILE * prn_stream,const char * init,int init_size,const char * end,int end_size)104 can_print_page(gx_device_printer *pdev, FILE *prn_stream,
105 const char *init, int init_size, const char *end, int end_size)
106 {
107 char data[LINE_SIZE*2];
108 char *out_data;
109 int last_line_nro = 0;
110
111 fwrite(init, init_size, 1, prn_stream); /* initialize */
112
113 /* Send each scan line in turn */
114 {
115 int lnum;
116 int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
117 byte rmask = (byte)(0xff << (-pdev->width & 7));
118
119 for ( lnum = 0; lnum < pdev->height; lnum++ ) {
120 char *end_data = data + LINE_SIZE;
121 gdev_prn_copy_scan_lines(pdev, lnum,
122 (byte *)data, line_size);
123 /* Mask off 1-bits beyond the line width. */
124 end_data[-1] &= rmask;
125 /* Remove trailing 0s. */
126 while ( end_data > data && end_data[-1] == 0 )
127 end_data--;
128 if ( end_data != data ) {
129 int num_cols = 0;
130 int out_count;
131 int zero_count;
132 out_data = data;
133
134 /* move down */
135 fprintf(prn_stream, "%c[%de",
136 ESC, lnum-last_line_nro );
137 last_line_nro = lnum;
138
139 while (out_data < end_data) {
140 /* Remove leading 0s*/
141 while(out_data < end_data && *out_data == 0) {
142 num_cols += 8;
143 out_data++;
144 }
145
146 out_count = end_data - out_data;
147 zero_count = 0;
148
149 /* if there is a lot data, find if there is sequence of zeros */
150 if (out_count>22) {
151
152 out_count = 1;
153
154 while(out_data+out_count+zero_count < end_data) {
155 if (out_data[zero_count+out_count] != 0) {
156 out_count += 1+zero_count;
157 zero_count = 0;
158 }
159 else {
160 zero_count++;
161 if (zero_count>20)
162 break;
163 }
164 }
165
166 }
167
168 if (out_count==0)
169 break;
170
171 /* move down and across*/
172 fprintf(prn_stream, "%c[%d`",
173 ESC, num_cols );
174 /* transfer raster graphic command */
175 fprintf(prn_stream, "%c[%d;%d;300;.r",
176 ESC, out_count, out_count);
177
178 /* send the row */
179 fwrite(out_data, sizeof(char),
180 out_count, prn_stream);
181
182 out_data += out_count+zero_count;
183 num_cols += 8*(out_count+zero_count);
184 }
185 }
186 }
187 }
188
189 /* eject page */
190 fprintf(prn_stream, "%c=", ESC);
191
192 /* terminate */
193 if (end != NULL)
194 fwrite(end, end_size, 1, prn_stream);
195
196 return 0;
197 }
198
199 /* Print an LBP-8 page. */
200 private int
lbp8_print_page(gx_device_printer * pdev,FILE * prn_stream)201 lbp8_print_page(gx_device_printer *pdev, FILE *prn_stream)
202 { return can_print_page(pdev, prn_stream, lbp8_init, sizeof(lbp8_init),
203 lbp8_end, sizeof(lbp8_end));
204 }
205
206 /* Print a LIPS III page. */
207 private int
lips3_print_page(gx_device_printer * pdev,FILE * prn_stream)208 lips3_print_page(gx_device_printer *pdev, FILE *prn_stream)
209 { return can_print_page(pdev, prn_stream, lips3_init, sizeof(lips3_init),
210 lips3_end, sizeof(lips3_end));
211 }
212