2 |
- |
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
|
|
|
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
|
|
|
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
|
|
|
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 |
}
|