Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1990, 1995, 1997, 2000 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: gdevbj10.c,v 1.9 2004/08/04 19:36:12 stefan Exp $*/
18
/* Canon Bubble Jet BJ-10e, BJ200, and BJ300 printer driver */
19
#include "gdevprn.h"
20
 
21
/*
22
 * The following is taken from the BJ200 Programmer's manual.  The top
23
 * margin is 3mm (0.12"), and the bottom margin is 6.4mm (0.25").  The
24
 * left and right margin depend on the type of paper -- US letter or
25
 * A4 -- but ultimately rest on a print width of 203.2mm (8").  For letter
26
 * paper, the left margin (and hence the right) is 6.4mm (0.25"), while
27
 * for A4 paper, both are 3.4mm (0.13").
28
 *
29
 * The bottom margin requires a bit of care.  The image is printed
30
 * as strips, each about 3.4mm wide.  We can only attain the bottom 
31
 * margin if the final strip coincides with it.  Note that each strip
32
 * is generated using only 48 of the available 64 jets, and the absence
33
 * of those bottom 16 jets makes our bottom margin, in effect, about
34
 * 1.1mm (0.04") larger.
35
 *
36
 * The bj200 behaves, in effect, as though the origin were at the first
37
 * printable position, rather than the top left corner of the page, so
38
 * we add a translation to the initial matrix to compensate for this.
39
 *
40
 * Except for the details of getting the margins correct, the bj200 is
41
 * no different from the bj10e, and uses the same routine to print each
42
 * page.
43
 *
44
 * NOTE:  The bj200 has a DIP switch called "Text scale mode" and if
45
 * set, it allows the printer to get 66 lines on a letter-sized page
46
 * by reducing the line spacing by a factor of 14/15.  If this DIP
47
 * switch is set, the page image printed by ghostscript will also be
48
 * similarly squeezed.  Thus text scale mode is something ghostscript
49
 * would like to disable.
50
 *
51
 * According to the bj200 manual, which describes the bj10 commands,
52
 * the printer can be reset either to the settings determined by the
53
 * DIP switches, or to the factory defaults, and then some of those
54
 * settings can be specifically overriden.  Unfortunately, the text
55
 * scale mode and horizontal print position (for letter vs A4 paper)
56
 * can not be overriden.  On my bj200, the factory settings are for
57
 * no text scaling and letter paper, thus using the factory defaults
58
 * also implies letter paper.  I don't know if this is necessarily
59
 * true for bj200's sold elsewhere, or for other printers that use
60
 * the same command set.
61
 *
62
 * If your factory defaults are in fact the same, you can compile
63
 * the driver with USE_FACTORY_DEFAULTS defined, in which case the
64
 * printer will be reset to the factory defaults for letter paper,
65
 * and reset to the DIP switch settings for A4 paper.  In this case,
66
 * with letter-sized paper, the text scale mode will be disabled.
67
 * Further, by leaving the horizontal print position DIP switch set
68
 * for A4 paper, gs will be able to print on either A4 or letter
69
 * paper without changing the DIP switch.  Since it's not clear that
70
 * the factory defaults are universal, the default behaviour is not
71
 * to define USE_FACTORY_DEFAULTS, and the printer will always be
72
 * reset to the DIP switch defaults.
73
 */
74
 
75
/*
76
 * According to md@duesti.fido.de (Matthias Duesterhoeft):
77
 
78
It is possible to use the printer Canon BJ-300 (and 330) with Ghostscript if
79
you use the driver for the Canon BJ-200. The Printer has to be set to
80
Proprinter Mode. Although it is possible to set the print quality with a DIP
81
switch, you should add the following to the already existing init-string:
82
1B 5B 64 01 00 80  (all numbers in hex)
83
This sets the print quality to letter quality.
84
 
85
The minimum margins are the following:
86
 
87
Portrait:
88
B5/A4: min. left and right margin: 3.4 mm (0.13")
89
Letter: min. left and right margin: 6.4 mm (0.25")
90
 
91
Landscape:
92
B4: min. left and right margin: 9.3 mm (0.37")
93
A3: min. left and right margin: 37.3 mm (1.47")
94
 
95
The recommended top margin is 12.7 mm (0.5"), although the printer is capable
96
to start at 0 mm. The recommended bottom margin is 25.4 mm (1"), but 12.7 mm
97
(0.5") are possible, too. If you ask me, don't use the recommended top and
98
bottom margins, use 0" and 0.5".
99
 
100
 */
101
 
102
#define BJ200_TOP_MARGIN		0.12
103
#define BJ200_BOTTOM_MARGIN		0.29
104
#define BJ200_LETTER_SIDE_MARGIN	0.25
105
#define BJ200_A4_SIDE_MARGIN		0.13
106
 
107
private dev_proc_open_device(bj200_open);
108
 
109
private dev_proc_print_page(bj10e_print_page);
110
 
111
private gx_device_procs prn_bj200_procs =
112
  prn_procs(bj200_open, gdev_prn_output_page, gdev_prn_close);
113
 
114
const gx_device_printer far_data gs_bj200_device =
115
  prn_device(prn_bj200_procs, "bj200",
116
	DEFAULT_WIDTH_10THS,
117
	DEFAULT_HEIGHT_10THS,
118
	360,				/* x_dpi */
119
	360,				/* y_dpi */
120
	0, 0, 0, 0,			/* margins filled in by bj200_open */
121
	1, bj10e_print_page);
122
 
123
/*
124
 * (<simon@pogner.demon.co.uk>, aka <sjwright@cix.compulink.co.uk>):
125
 * My bj10ex, which as far as I can tell is just like a bj10e, needs a
126
 * bottom margin of 0.4" (actually, you must not print within 0.5" of
127
 * the bottom; somewhere, an extra 0.1" is creeping in).
128
 *
129
 * (<jim.hague@acm.org>):
130
 * I have a BJ10sx and the BJ10sx manual. This states that the top and
131
 * bottom margins for the BJ10sx are 0.33" and 0.5". The latter may
132
 * explain Simon's finding. The manual also instructs Win31 users to
133
 * select 'BJ10e' as their driver, so presumably the margins will be
134
 * identical and thus also correct for BJ10e. The values for the side
135
 * margins given are identical to those above.
136
 *
137
 * As of 2nd Nov 2001 the BJ10 sx manual is at
138
 * http://www.precision.com/Printer%20Manuals/Canon%20BJ-10sx%20Manual.pdf.
139
 */
140
 
141
#define BJ10E_TOP_MARGIN		0.33
142
#define BJ10E_BOTTOM_MARGIN		(0.50 + 0.04)
143
 
144
private dev_proc_open_device(bj10e_open);
145
 
146
private gx_device_procs prn_bj10e_procs =
147
  prn_procs(bj10e_open, gdev_prn_output_page, gdev_prn_close);
148
 
149
const gx_device_printer far_data gs_bj10e_device =
150
  prn_device(prn_bj10e_procs, "bj10e",
151
	DEFAULT_WIDTH_10THS,
152
	DEFAULT_HEIGHT_10THS,
153
	360,				/* x_dpi */
154
	360,				/* y_dpi */
155
	0,0,0,0,			/* margins */
156
	1, bj10e_print_page);
157
 
158
/*
159
 * Notes on the BJ10e/BJ200 command set.
160
 *
161
 
162
According to the BJ200 manual, the "set initial condition" sequence (ESC [
163
K) has 2 bytes which can override the DIP switches -- these are the last 2
164
bytes.  Several bits are listed as "reserved" -- one or more may possibly
165
affect the sheet feeder.  The first is referred to as <P1>, with the
166
following meaning:
167
				1		0
168
bit 7	ignore/process P1	ignore		process
169
bit 6	reserved
170
bit 5	alarm			disabled	enabled
171
bit 4	automatic CR		CR+LF		CR
172
bit 3	automatic LF		CR+LF		LF
173
bit 2	page length		12 inches	11 inches
174
bit 1	style for zero		slashed		not slashed
175
bit 0	character set		set 2		set 1
176
 
177
The last byte is <P2>, with the following meaning:
178
				1		0
179
bit 7	ignore/process P2	ignore		process
180
bit 6	code page		850		437
181
bit 5	reserved
182
bit 4	reserved
183
bit 3	reserved
184
bit 2	reserved
185
bit 1	reserved
186
bit 0	reserved
187
 
188
The automatic CR setting is important to gs, but the rest shouldn't matter
189
(gs doesn't print characters or send LF, and it explicitly sets the page
190
length).  The sequence ESC 5 <n> controls automatic CR -- if <n> is 0x00,
191
it is turned off (CR only) and if <n> is 0x01, it is turned on (CR + LF).
192
So we do following: Change the initialization string to so that the last 2
193
of the 9 bytes are \200 rather than \000.  Then add
194
	|* Turn off automatic carriage return, otherwise we get line feeds. *|
195
	fwrite("\0335\000", 1, 3, prn_stream);
196
after the initialization.  (Actually, instead of setting the last 2 bytes
197
to \200, we suppress them altogether by changing the byte count from \004
198
to \002 (the byte count is the 4th (low 8 bits) and 5th (high 8 bits) bytes
199
in the initialization sequence).)
200
 
201
*/
202
 
203
/* ------ Internal routines ------ */
204
 
205
/* Open the printer, and set the margins. */
206
private int
207
bj200_open(gx_device *pdev)
208
{
209
	/* Change the margins according to the paper size.
210
	   The top and bottom margins don't seem to depend on the
211
	   page length, but on the paper handling mechanism;
212
	   The side margins do depend on the paper width, as the
213
	   printer centres the 8" print line on the page. */
214
 
215
	static const float a4_margins[4] =
216
	 {	(float)BJ200_A4_SIDE_MARGIN, (float)BJ200_BOTTOM_MARGIN,
217
		(float)BJ200_A4_SIDE_MARGIN, (float)BJ200_TOP_MARGIN
218
	 };
219
	static const float letter_margins[4] =
220
	 {	(float)BJ200_LETTER_SIDE_MARGIN, (float)BJ200_BOTTOM_MARGIN,
221
		(float)BJ200_LETTER_SIDE_MARGIN, (float)BJ200_TOP_MARGIN
222
	 };
223
 
224
	gx_device_set_margins(pdev,
225
		(pdev->width / pdev->x_pixels_per_inch <= 8.4 ?
226
		 a4_margins : letter_margins),
227
		true);
228
	return gdev_prn_open(pdev);
229
}
230
 
231
private int
232
bj10e_open(gx_device *pdev)
233
{
234
        /* See bj200_open() */
235
	static const float a4_margins[4] =
236
	 {	(float)BJ200_A4_SIDE_MARGIN, (float)BJ10E_BOTTOM_MARGIN,
237
		(float)BJ200_A4_SIDE_MARGIN, (float)BJ10E_TOP_MARGIN
238
	 };
239
	static const float letter_margins[4] =
240
	 {	(float)BJ200_LETTER_SIDE_MARGIN, (float)BJ10E_BOTTOM_MARGIN,
241
		(float)BJ200_LETTER_SIDE_MARGIN, (float)BJ10E_TOP_MARGIN
242
	 };
243
 
244
	gx_device_set_margins(pdev,
245
		(pdev->width / pdev->x_pixels_per_inch <= 8.4 ?
246
		 a4_margins : letter_margins),
247
		true);
248
	return gdev_prn_open(pdev);
249
}
250
 
251
/* Send the page to the printer. */
252
private int
253
bj10e_print_page(gx_device_printer *pdev, FILE *prn_stream)
254
{	int line_size = gx_device_raster((gx_device *)pdev, 0);
255
	int xres = (int)pdev->x_pixels_per_inch;
256
	int yres = (int)pdev->y_pixels_per_inch;
257
	int mode = (yres == 180 ?
258
			(xres == 180 ? 11 : 12) :
259
			(xres == 180 ? 14 : 16));
260
	int bytes_per_column = (yres == 180) ? 3 : 6;
261
	int bits_per_column = bytes_per_column * 8;
262
	int skip_unit = bytes_per_column * 3;
263
	byte *in = (byte *)gs_malloc(pdev->memory, 8, line_size, "bj10e_print_page(in)");
264
	byte *out = (byte *)gs_malloc(pdev->memory, bits_per_column, line_size, "bj10e_print_page(out)");
265
	int lnum = 0;
266
	int skip = 0;
267
	int code = 0;
268
	int last_row = dev_print_scan_lines(pdev);
269
	int limit = last_row - bits_per_column;
270
 
271
	if ( in == 0 || out == 0 )
272
	{	code = gs_note_error(gs_error_VMerror);
273
		goto fin;
274
	}
275
 
276
	/* Initialize the printer. */
277
#ifdef USE_FACTORY_DEFAULTS
278
	/* Check for U.S. letter vs. A4 paper. */
279
	fwrite(( pdev->width / pdev->x_pixels_per_inch <= 8.4 ?
280
		"\033[K\002\000\000\044"	/*A4--DIP switch defaults*/ :
281
		"\033[K\002\000\004\044"	/*letter--factory defaults*/ ),
282
	       1, 7, prn_stream);
283
#else
284
	fwrite("\033[K\002\000\000\044", 1, 7, prn_stream);
285
#endif
286
 
287
	/* Turn off automatic carriage return, otherwise we get line feeds. */
288
	fwrite("\0335\000", 1, 3, prn_stream);
289
 
290
	/* Set vertical spacing. */
291
	fwrite("\033[\\\004\000\000\000", 1, 7, prn_stream);
292
	fputc(yres & 0xff, prn_stream);
293
	fputc(yres >> 8, prn_stream);
294
 
295
	/* Set the page length.  This is the printable length, in inches. */
296
	fwrite("\033C\000", 1, 3, prn_stream);
297
	fputc((last_row + yres - 1)/yres, prn_stream);
298
 
299
	/* Transfer pixels to printer.  The last row we can print is defined
300
	   by "last_row".  Only the bottom of the print head can print at the
301
	   bottom margin, and so we align the final printing pass.  The print
302
	   head is kept from moving below "limit", which is exactly one pass
303
	   above the bottom margin.  Once it reaches this limit, we make our
304
	   final printing pass of a full "bits_per_column" rows. */
305
	while ( lnum < last_row )
306
	   {	
307
		byte *in_data;
308
		byte *in_end = in + line_size;
309
		byte *out_beg = out;
310
		byte *out_end = out + bytes_per_column * pdev->width;
311
		byte *outl = out;
312
		int bnum;
313
 
314
		/* Copy 1 scan line and test for all zero. */
315
		code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
316
		if ( code < 0 ) goto xit;
317
		/* The mem... or str... functions should be faster than */
318
		/* the following code, but all systems seem to implement */
319
		/* them so badly that this code is faster. */
320
		   {	register const long *zip = (const long *)in_data;
321
			register int zcnt = line_size;
322
			register const byte *zipb;
323
			for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) )
324
			   {	if ( zip[0] | zip[1] | zip[2] | zip[3] )
325
					goto notz;
326
			   }
327
			zipb = (const byte *)zip;
328
			while ( --zcnt >= 0 )
329
			   {
330
				if ( *zipb++ )
331
					goto notz;
332
			   }
333
			/* Line is all zero, skip */
334
			lnum++;
335
			skip++;
336
			continue;
337
notz:			;
338
		   }
339
 
340
		/* Vertical tab to the appropriate position.  Note here that
341
		   we make sure we don't move below limit. */
342
		if ( lnum > limit )
343
		    {	skip -= (lnum - limit);
344
			lnum = limit;
345
		    }
346
		while ( skip > 255 )
347
		   {	fputs("\033J\377", prn_stream);
348
			skip -= 255;
349
		   }
350
		if ( skip )
351
			fprintf(prn_stream, "\033J%c", skip);
352
 
353
		/* If we've printed as far as "limit", then reset "limit"
354
		   to "last_row" for the final printing pass. */
355
		if ( lnum == limit )
356
			limit = last_row;
357
		skip = 0;
358
 
359
		/* Transpose in blocks of 8 scan lines. */
360
		for ( bnum = 0; bnum < bits_per_column; bnum += 8 )
361
		   {	int lcnt = min(8, limit - lnum);
362
			byte *inp = in;
363
			byte *outp = outl;
364
		   	lcnt = gdev_prn_copy_scan_lines(pdev,
365
				lnum, in, lcnt * line_size);
366
			if ( lcnt < 0 )
367
			   {	code = lcnt;
368
				goto xit;
369
			   }
370
			if ( lcnt < 8 )
371
				memset(in + lcnt * line_size, 0,
372
				       (8 - lcnt) * line_size);
373
			for ( ; inp < in_end; inp++, outp += bits_per_column )
374
			   {	gdev_prn_transpose_8x8(inp, line_size,
375
					outp, bytes_per_column);
376
			   }
377
			outl++;
378
			lnum += lcnt;
379
			skip += lcnt;
380
		   }
381
 
382
		/* Send the bits to the printer.  We alternate horizontal
383
		   skips with the data.  The horizontal skips are in units
384
		   of 1/120 inches, so we look at the data in groups of
385
		   3 columns, since 3/360 = 1/120, and 3/180 = 2/120.  */
386
		outl = out;
387
		do
388
		   {	int count;
389
			int n;
390
			byte *out_ptr;
391
 
392
			/* First look for blank groups of columns. */
393
			while(outl < out_end)
394
			   {	n = count = min(out_end - outl, skip_unit);
395
				out_ptr = outl;
396
				while ( --count >= 0 )
397
				   {	if ( *out_ptr++ )
398
						break;
399
				   }
400
				if ( count >= 0 )
401
					break;
402
				else
403
					outl = out_ptr;
404
			   }
405
			if (outl >= out_end)
406
				break;
407
			if (outl > out_beg)
408
			   {	count = (outl - out_beg) / skip_unit;
409
				if ( xres == 180 ) count <<= 1;
410
				fprintf(prn_stream, "\033d%c%c",
411
					count & 0xff, count >> 8);
412
			   }
413
 
414
			/* Next look for non-blank groups of columns. */
415
			out_beg = outl;
416
			outl += n;
417
			while(outl < out_end)
418
			   {	n = count = min(out_end - outl, skip_unit);
419
				out_ptr = outl;
420
				while ( --count >= 0 )
421
				   {	if ( *out_ptr++ )
422
						break;
423
				   }
424
				if ( count < 0 )
425
					break;
426
				else
427
					outl += n;
428
			   }
429
			count = outl - out_beg + 1;
430
			fprintf(prn_stream, "\033[g%c%c%c",
431
				count & 0xff, count >> 8, mode);
432
			fwrite(out_beg, 1, count - 1, prn_stream);
433
			out_beg = outl;
434
			outl += n;
435
		   }
436
		while ( out_beg < out_end );
437
 
438
		fputc('\r', prn_stream);
439
	   }
440
 
441
	/* Eject the page */
442
xit:	fputc(014, prn_stream);	/* form feed */
443
	fflush(prn_stream);
444
fin:	if ( out != 0 )
445
		gs_free(pdev->memory, (char *)out, bits_per_column, line_size,
446
			"bj10e_print_page(out)");
447
	if ( in != 0 )
448
		gs_free(pdev->memory, (char *)in, 8, line_size, "bj10e_print_page(in)");
449
	return code;
450
}