1 /* Copyright (C) 1991, 1994, 1996, 1997 artofcode LLC. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16
17 */
18
19 /*$Id: gdevlbp8.c,v 1.3.2.1.2.1 2003/01/17 00:49:00 giles Exp $*/
20 /* Canon LBP-8II and LIPS III driver */
21 #include "gdevprn.h"
22
23 /*
24 Modifications:
25 3.10.00 Johnny Lam
26 Removed LIPS III code, as it's obsoleted by gdevlips driver.
27 2.2.97 Lauri Paatero
28 Changed CSI command into ESC [. DCS commands may still need to be changed
29 (to ESC P).
30 4.9.96 Lauri Paatero
31 Corrected LBP-8II margins again. Real problem was that (0,0) is NOT
32 in upper left corner.
33 Now using relative addressing for vertical addressing. This avoids
34 problems
35 when printing to paper with wrong size.
36 18.6.96 Lauri Paatero, lauri.paatero@paatero.pp.fi
37 Corrected LBP-8II margins.
38 Added logic to recognize (and optimize away) long strings of 00's in data.
39 For LBP-8II removed use of 8-bit CSI (this does not work if 8-bit character
40 set has been configured in LBP-8II. (Perhaps this should also be done
41 for LBP-8III?)
42 Original versions:
43 LBP8 driver: Tom Quinn (trq@prg.oxford.ac.uk)
44 LIPS III driver: Kenji Okamoto (okamoto@okamoto.cias.osakafu-u.ac.jp)
45 */
46
47
48 #define X_DPI 300
49 #define Y_DPI 300
50 #define LINE_SIZE ((X_DPI * 85 / 10 + 7) / 8) /* bytes per line */
51
52 /* The device descriptors */
53 private dev_proc_print_page(lbp8_print_page);
54
55 const gx_device_printer far_data gs_lbp8_device =
56 prn_device(prn_std_procs, "lbp8",
57 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
58 X_DPI, Y_DPI,
59 0.16, 0.2, 0.32, 0.21, /* margins: left, bottom, right, top */
60 1, lbp8_print_page);
61
62 /* ------ Internal routines ------ */
63
64 #define ESC 0x1b
65 #define CSI 0233
66 #define DCS 0220
67 #define ST 0234
68
69 static const char lbp8_init[] = {
70 ESC, ';', ESC, 'c', ESC, ';', /* reset, ISO */
71 ESC, '[', '2', '&', 'z', /* fullpaint mode */
72 ESC, '[', '1', '4', 'p', /* select page type (A4) */
73 ESC, '[', '1', '1', 'h', /* set mode */
74 ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
75 ESC, '[', '6', '3', 'k', /* Move 63 dots up (to top of printable area) */
76 };
77
78 static const char *lbp8_end = NULL;
79
80 /* Send the page to the printer. */
81 private int
can_print_page(gx_device_printer * pdev,FILE * prn_stream,const char * init,int init_size,const char * end,int end_size)82 can_print_page(gx_device_printer *pdev, FILE *prn_stream,
83 const char *init, int init_size, const char *end, int end_size)
84 {
85 char data[LINE_SIZE*2];
86 char *out_data;
87 int last_line_nro = 0;
88
89 fwrite(init, init_size, 1, prn_stream); /* initialize */
90
91 /* Send each scan line in turn */
92 {
93 int lnum;
94 int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
95 byte rmask = (byte)(0xff << (-pdev->width & 7));
96
97 for ( lnum = 0; lnum < pdev->height; lnum++ ) {
98 char *end_data = data + LINE_SIZE;
99 gdev_prn_copy_scan_lines(pdev, lnum,
100 (byte *)data, line_size);
101 /* Mask off 1-bits beyond the line width. */
102 end_data[-1] &= rmask;
103 /* Remove trailing 0s. */
104 while ( end_data > data && end_data[-1] == 0 )
105 end_data--;
106 if ( end_data != data ) {
107 int num_cols = 0;
108 int out_count;
109 int zero_count;
110 out_data = data;
111
112 /* move down */
113 fprintf(prn_stream, "%c[%de",
114 ESC, lnum-last_line_nro );
115 last_line_nro = lnum;
116
117 while (out_data < end_data) {
118 /* Remove leading 0s*/
119 while(out_data < end_data && *out_data == 0) {
120 num_cols += 8;
121 out_data++;
122 }
123
124 out_count = end_data - out_data;
125 zero_count = 0;
126
127 /* if there is a lot data, find if there is sequence of zeros */
128 if (out_count>22) {
129
130 out_count = 1;
131
132 while(out_data+out_count+zero_count < end_data) {
133 if (out_data[zero_count+out_count] != 0) {
134 out_count += 1+zero_count;
135 zero_count = 0;
136 }
137 else {
138 zero_count++;
139 if (zero_count>20)
140 break;
141 }
142 }
143
144 }
145
146 if (out_count==0)
147 break;
148
149 /* move down and across*/
150 fprintf(prn_stream, "%c[%d`",
151 ESC, num_cols );
152 /* transfer raster graphic command */
153 fprintf(prn_stream, "%c[%d;%d;300;.r",
154 ESC, out_count, out_count);
155
156 /* send the row */
157 fwrite(out_data, sizeof(char),
158 out_count, prn_stream);
159
160 out_data += out_count+zero_count;
161 num_cols += 8*(out_count+zero_count);
162 }
163 }
164 }
165 }
166
167 /* eject page */
168 fprintf(prn_stream, "%c=", ESC);
169
170 /* terminate */
171 if (end != NULL)
172 fwrite(end, end_size, 1, prn_stream);
173
174 return 0;
175 }
176
177 /* Print an LBP-8 page. */
178 private int
lbp8_print_page(gx_device_printer * pdev,FILE * prn_stream)179 lbp8_print_page(gx_device_printer *pdev, FILE *prn_stream)
180 { return can_print_page(pdev, prn_stream, lbp8_init, sizeof(lbp8_init),
181 lbp8_end, sizeof(lbp8_end));
182 }
183