1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
13
/* $Id: gdevo182.c 8250 2007-09-25 13:31:24Z giles $*/
14
/* Okidata Microline 182 printer driver */
16
/* Contributed by Maarten Koning (smeg@bnr.ca) April 4, 1993 */
18
/****************************************************************
20
I use this driver from Unix with the following aliases:
22
alias psp "gs -q -sDEVICE=oki182 -sOutputFile=\|lpr - <\!*"
23
alias psphigh "gs -q -sDEVICE=oki182 -r144 -sOutputFile=\|lpr - <\!*"
25
ps. I have my printer DIP switches set to the following (as viewed
26
while standing in front of your printer looking down into the
27
config access hatch located at the top of your printer
42
The upper DIP switches are on a SuperSpeed Serial
43
card that will do 19200 baud. I have it set at 9600
44
baud since that seems sufficient to keep the printer
47
The important thing is to be in 8-bit mode so that
48
the graphics data can't match any Okidata commands
49
(This driver sets the high bit of graphics data to 1).
51
****************************************************************/
56
* Available resolutions are 72x72 or 144x144;
57
* (144x72) would be possible to do also, but I didn't bother)
60
/* The device descriptor */
62
static dev_proc_print_page(oki_print_page);
64
const gx_device_printer far_data gs_oki182_device =
65
prn_device(prn_std_procs, "oki182",
66
80, /* width_10ths, 8.0" */
67
110, /* height_10ths, 11" */
70
0, 0, 0, 0, /* margins */
73
/* ------ internal routines ------ */
75
/* out is a pointer to an array of 7 scan lines,
76
lineSize is the number of bytes between a pixel and
77
the pixel directly beneath it.
78
scanBits is the number of bits in each scan line
79
out is a pointer to an array of column data, which
80
is how the Okidata wants the graphics image.
82
each column of graphics data is 7 bits high and
83
is encoded in a byte - highest pixel in the column
84
is the lowest bit in the byte. The upper bit of the
85
byte is set so that the okidata doesn't mistake
86
graphic image data for graphic commands.
90
oki_transpose(byte *in, byte *out, int scanBits, register int lineSize)
92
register bitMask = 0x80;
94
register byte outByte;
96
while (scanBits-- > 0) {
100
if (*inPtr & bitMask)
104
if (*(inPtr += lineSize) & bitMask)
106
if (*(inPtr += lineSize) & bitMask)
108
if (*(inPtr += lineSize) & bitMask)
110
if (*(inPtr += lineSize) & bitMask)
112
if (*(inPtr += lineSize) & bitMask)
114
if (*(inPtr += lineSize) & bitMask)
119
if ((bitMask >>= 1) == 0) {
126
/* This routine tries to compress a sequence of okidata
127
graphic bytes by trimming off leading and trailing
128
zeros. Trailing zeros can be thrown away and leading
129
zeros can be replaced with a much smaller number of spaces.
131
'in' is a pointer to the graphic bytes to be compressed.
132
origWidth is the number of bytes pointed to by 'in'.
133
highRes is non-zero when 144x144 mode is being used.
135
numSpaces is set to the number of spaces that should
136
be printed before the compressed image. newWidth is
137
the new number of bytes that the return value of this
140
xxx - A future enhancement would be to replace long sequences
141
of embedded zeros with exit.graphics-<n> spaces-enter.graphics
144
oki_compress(byte *in, int origWidth, int highRes,
145
int *numSpaces, int *newWidth)
148
int columns_per_space = 6;
150
byte *in_end = in + origWidth;
152
/* remove trailing zeros (which are realy 0x80's) */
153
while (in_end > in && in_end[-1] == 0x80)
157
columns_per_space = 12;
159
/* remove leading zeros that can be replaced by spaces */
160
while(in < in_end && in[0] == 0x80 && memcmp((char *)in,
161
(char *)in + 1, columns_per_space - 1) == 0) {
163
in += columns_per_space;
168
/* just in case we compressed this line out of existance */
170
*newWidth = in_end - in;
177
/* Send the page to the printer. */
180
oki_print_page(gx_device_printer *pdev, FILE *prn_stream)
182
int highRes = pdev->y_pixels_per_inch > 100;
183
int bits_per_column = 7;
184
int i, spaces, width;
187
int line_size = gdev_prn_raster((gx_device_printer *)pdev);
189
byte *in = (byte *)gs_malloc(pdev->memory, 16, line_size, "oki_print_page(in)");
191
byte *out1 = (byte *)gs_malloc(pdev->memory, 8, line_size, "oki_print_page(out1)");
192
byte *out2 = (byte *)gs_malloc(pdev->memory, 8, line_size, "oki_print_page(out2)");
200
if ( in == 0 || out1 == 0 || out2 == 0)
201
{ code = gs_error_VMerror;
206
/* Initialize the printer. */
207
/* CAN; 72x72; left margin = 001; disable skip over perforation */
208
fwrite("\030\034\033%C001\033%S0", 1, 12, prn_stream);
211
fwrite("\033R", 1, 2, prn_stream);
212
bits_per_column = 14;
215
/* Transfer pixels to printer */
216
while ( lnum < pdev->height ) {
218
/* Copy 1 scan line and test for all zero. */
219
code = gdev_prn_copy_scan_lines(pdev, lnum, in, line_size);
223
/* if line is all zero, skip */
224
if ( in[0] == 0 && !memcmp((char *)in, (char *)in + 1,
234
/* use fine line feed to get to the appropriate position. */
235
while ( skip > 127 ) {
236
fputs("\033%5\177", prn_stream);
240
fprintf(prn_stream, "\033%%5%c",
241
(char) (skip & 0xff));
244
/* get the rest of the scan lines */
245
code = gdev_prn_copy_scan_lines(pdev, lnum + 1,
246
in + line_size, (bits_per_column - 1) * line_size);
251
lcnt = code + 1; /* since we already grabbed one line */
253
if ( lcnt < bits_per_column )
254
memset(in + lcnt * line_size, 0,
255
(bits_per_column - lcnt) * line_size);
258
oki_transpose(in, out1, pdev->width, 2 * line_size);
259
oki_transpose(in + line_size, out2,
260
pdev->width, 2 * line_size);
262
oki_transpose(in, out1, pdev->width, line_size);
264
out3 = oki_compress(out1, pdev->width, highRes,
267
for (i=0; i < spaces; i++)
268
putc(' ', prn_stream);
270
fwrite("\003", 1, 1, prn_stream);
271
fwrite(out3, 1, width, prn_stream);
274
/* exit graphics; carriage return; 1 bit line feed */
275
fprintf(prn_stream, "\003\002\015\033%%5%c", (char) 1);
276
out3 = oki_compress(out2, pdev->width, highRes,
278
for (i=0; i < spaces; i++)
279
putc(' ', prn_stream);
280
fwrite("\003", 1, 1, prn_stream);
281
fwrite(out3, 1, width, prn_stream);
282
fprintf(prn_stream, "\003\002\015\033%%5%c", (char) 13);
284
fwrite("\003\016\003\002", 1, 4, prn_stream);
286
lnum += bits_per_column;
291
fputc(014, prn_stream); /* form feed */
296
gs_free(pdev->memory, (char *)out1, 8, line_size, "oki_print_page(out1)");
299
gs_free(pdev->memory, (char *)out2, 8, line_size, "oki_print_page(out2)");
302
gs_free(pdev->memory, (char *)in, 16, line_size, "oki_print_page(in)");