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