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: gdevl31s.c 8250 2007-09-25 13:31:24Z giles $ */
15
* H-P LaserJet 3100 driver
17
* This is a driver for use with the H-P LaserJet 3100 Software.
18
* It requires installed H-P LaserJet 3100 Software to print.
19
* It can be used with smbclient to print from an UNIX box
20
* to a LaserJet 3100 printer attached to a MS-Windows box.
22
* Written by Ulrich Schmid, uschmid@mail.hh.provi.de.
28
#define XCORRECTION 0.11
29
#define YCORRECTION 0.12
31
/* order matters! 0 1 2 3 4 5 6 7 8 */
32
const char *media[10] = {"a4", "letter", "legal", "com10", "c5", "dl", "b5", "monarch", "executive", 0};
33
const int height[2][10] = {{3447, 3240, 4140, 5587, 2644, 5083, 2975, 4387, 3090, 0},
34
{6894, 6480, 8280, 11167, 5288, 10159, 5950, 8767, 6180, 0}};
35
const int width[2] = {2528,
37
#define LARGEST_MEDIUM 2 /* legal */
39
/* These codes correspond to sequences of pixels with the same color.
40
* After the code for a sequence < 64 pixels the color changes.
41
* After the code for a sequence with 64 pixels the previous color continues. */
44
uint length; /* number of valid bits */
47
{{{0x0ac, 8}, {0x038, 6}, {0x00e, 4}, {0x001, 4}, {0x00d, 4}, {0x003, 4}, {0x007, 4}, {0x00f, 4},
48
{0x019, 5}, {0x005, 5}, {0x01c, 5}, {0x002, 5}, {0x004, 6}, {0x030, 6}, {0x00b, 6}, {0x02b, 6},
49
{0x015, 6}, {0x035, 6}, {0x072, 7}, {0x018, 7}, {0x008, 7}, {0x074, 7}, {0x060, 7}, {0x010, 7},
50
{0x00a, 7}, {0x06a, 7}, {0x064, 7}, {0x012, 7}, {0x00c, 7}, {0x040, 8}, {0x0c0, 8}, {0x058, 8},
51
{0x0d8, 8}, {0x048, 8}, {0x0c8, 8}, {0x028, 8}, {0x0a8, 8}, {0x068, 8}, {0x0e8, 8}, {0x014, 8},
52
{0x094, 8}, {0x054, 8}, {0x0d4, 8}, {0x034, 8}, {0x0b4, 8}, {0x020, 8}, {0x0a0, 8}, {0x050, 8},
53
{0x0d0, 8}, {0x04a, 8}, {0x0ca, 8}, {0x02a, 8}, {0x0aa, 8}, {0x024, 8}, {0x0a4, 8}, {0x01a, 8},
54
{0x09a, 8}, {0x05a, 8}, {0x0da, 8}, {0x052, 8}, {0x0d2, 8}, {0x04c, 8}, {0x0cc, 8}, {0x02c, 8},
57
{{0x3b0, 10}, {0x002, 3}, {0x003, 2}, {0x001, 2}, {0x006, 3}, {0x00c, 4}, {0x004, 4}, {0x018, 5},
58
{0x028, 6}, {0x008, 6}, {0x010, 7}, {0x050, 7}, {0x070, 7}, {0x020, 8}, {0x0e0, 8}, {0x030, 9},
59
{0x3a0, 10}, {0x060, 10}, {0x040, 10}, {0x730, 11}, {0x0b0, 11}, {0x1b0, 11}, {0x760, 11}, {0x0a0, 11},
60
{0x740, 11}, {0x0c0, 11}, {0x530, 12}, {0xd30, 12}, {0x330, 12}, {0xb30, 12}, {0x160, 12}, {0x960, 12},
61
{0x560, 12}, {0xd60, 12}, {0x4b0, 12}, {0xcb0, 12}, {0x2b0, 12}, {0xab0, 12}, {0x6b0, 12}, {0xeb0, 12},
62
{0x360, 12}, {0xb60, 12}, {0x5b0, 12}, {0xdb0, 12}, {0x2a0, 12}, {0xaa0, 12}, {0x6a0, 12}, {0xea0, 12},
63
{0x260, 12}, {0xa60, 12}, {0x4a0, 12}, {0xca0, 12}, {0x240, 12}, {0xec0, 12}, {0x1c0, 12}, {0xe40, 12},
64
{0x140, 12}, {0x1a0, 12}, {0x9a0, 12}, {0xd40, 12}, {0x340, 12}, {0x5a0, 12}, {0x660, 12}, {0xe60, 12},
67
/* Define the default, maximum resolutions. */
75
/* The device descriptors */
76
static dev_proc_print_page_copies(lj3100sw_print_page_copies);
77
static dev_proc_close_device(lj3100sw_close);
79
static gx_device_procs prn_lj3100sw_procs =
80
prn_params_procs(gdev_prn_open, gdev_prn_output_page, lj3100sw_close,
81
gdev_prn_get_params, gdev_prn_put_params);
83
/* workaround to emulate the missing prn_device_margins_copies macro */
84
#define gx_default_print_page_copies lj3100sw_print_page_copies
85
gx_device_printer far_data gs_lj3100sw_device =
86
prn_device_margins/*_copies*/(prn_lj3100sw_procs, "lj3100sw",
87
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
89
XCORRECTION, YCORRECTION,
91
1, 0 /* lj3100sw_print_page_copies */);
92
#undef gx_default_print_page_copies
94
#define ppdev ((gx_device_printer *)pdev)
96
#define BUFFERSIZE 0x1000
99
lj3100sw_output_section_header(FILE *prn_stream, int type, int arg1, int arg2)
101
fputc(type & 0xff, prn_stream);
102
fputc(type >> 8 & 0xff, prn_stream);
103
fputc(arg1 & 0xff, prn_stream);
104
fputc(arg1 >> 8 & 0xff, prn_stream);
105
fputc(arg2 & 0xff, prn_stream);
106
fputc(arg2 >> 8 & 0xff, prn_stream);
110
lj3100sw_flush_buffer(FILE *prn_stream, char *buffer, char **pptr)
112
int size = *pptr - buffer;
114
lj3100sw_output_section_header(prn_stream, 0, size, 0);
115
fwrite(buffer, 1, size, prn_stream);
121
lj3100sw_output_data_byte(FILE *prn_stream, char *buffer, char **pptr, int val)
123
if (*pptr >= buffer + BUFFERSIZE)
124
lj3100sw_flush_buffer(prn_stream, buffer, pptr);
129
lj3100sw_output_repeated_data_bytes(FILE *prn_stream, char *buffer, char **pptr, int val, int num)
133
if (*pptr >= buffer + BUFFERSIZE)
134
lj3100sw_flush_buffer(prn_stream, buffer, pptr);
135
size = min(num, buffer + BUFFERSIZE - *pptr);
136
memset(*pptr, val, size);
143
lj3100sw_output_newline(FILE *prn_stream, char *buffer, char **pptr)
145
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0);
146
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0);
147
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
151
lj3100sw_output_empty_line(FILE *prn_stream, char *buffer, char **pptr, bool high_resolution)
153
if (high_resolution) {
154
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
155
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x0f);
156
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x78);
157
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0xac);
159
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
160
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x87);
161
lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x0d);
166
lj3100sw_print_page_copies(gx_device_printer *pdev, FILE *prn_stream, int num_copies /* ignored */)
169
char buffer[BUFFERSIZE], *ptr = buffer;
170
int medium_index = select_medium(pdev, media, LARGEST_MEDIUM);
171
bool high_resolution = (pdev->x_pixels_per_inch > 300);
172
int printer_height = height[high_resolution ? 1 : 0][medium_index];
173
int printer_width = width[high_resolution ? 1 : 0];
174
int paper_height = pdev->height;
175
int paper_width = pdev->width;
176
int line_size = gdev_prn_raster(pdev);
177
gs_memory_t *mem = pdev->memory;
178
byte *in = (byte *)gs_malloc(mem, line_size, 1, "lj3100sw_print_page");
181
return_error(gs_error_VMerror);
182
if (gdev_prn_file_is_new(pdev)) {
183
lj3100sw_output_section_header(prn_stream, 1, 0, 0);
184
lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12);
185
ptr += sprintf(ptr, "\r\nBD");
186
lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520);
187
ptr += sprintf(ptr, "%s\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n%s %d\r\n",
190
"RE", high_resolution ? 6 : 2,
195
lj3100sw_flush_buffer(prn_stream, buffer, &ptr);
198
lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0);
199
ptr += sprintf(ptr, "%s %d\r\n%s\r\n",
203
lj3100sw_output_newline(prn_stream, buffer, &ptr);
205
for (i = 0; i < printer_height; i++) {
206
if (i < paper_height) {
207
int color = 0; /* white */
211
gdev_prn_get_bits(pdev, i, in, &data);
212
for (j = 0; j <= printer_width; j++) {
213
int xoffset = (printer_width - paper_width) / 2;
215
if (j >= xoffset && j < xoffset + paper_width)
216
newcolor = (data[(j - xoffset) / 8] >> (7 - (j - xoffset) % 8)) & 1;
217
if (j == printer_width)
218
newcolor = !color; /* force output */
219
if (newcolor == color)
221
else if (count == printer_width && color == 0) /* implies j == printer_width */
222
lj3100sw_output_empty_line(prn_stream, buffer, &ptr, high_resolution);
223
else /* print a sequence of pixels with a uniform color */
224
while (newcolor != color) {
225
int size = min(count, 64);
226
tmp |= code[color][size].bits << bit_index;
227
bit_index += code[color][size].length;
228
while (bit_index >= 8) {
229
lj3100sw_output_data_byte(prn_stream, buffer, &ptr, tmp & 0xff);
242
lj3100sw_output_data_byte(prn_stream, buffer, &ptr, tmp & 0xff);
245
lj3100sw_output_empty_line(prn_stream, buffer, &ptr, high_resolution);
246
lj3100sw_output_newline(prn_stream, buffer, &ptr);
249
for (i = 0; i < 3; i++ ) {
250
lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x00);
251
lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x08);
252
lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x80);
254
lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 520);
255
lj3100sw_flush_buffer(prn_stream, buffer, &ptr);
257
lj3100sw_output_section_header(prn_stream, 4, 0, 0);
258
for (i = 0; i < 4 * ppdev->NumCopies; i++)
259
lj3100sw_output_section_header(prn_stream, 54, 0, 0);
261
gs_free(mem, (char *)in, line_size, 1, "lj3100sw_print_page");
266
lj3100sw_close(gx_device *pdev)
269
FILE *prn_stream = ((gx_device_printer *)pdev)->file;
271
lj3100sw_output_section_header(prn_stream, 0, 4, 0);
272
fputs("XX\r\n", prn_stream);
273
for (i = 0; i < 4 * ppdev->NumCopies; i++)
274
lj3100sw_output_section_header(prn_stream, 54, 0, 0);
275
lj3100sw_output_section_header(prn_stream, 2, 0, 0);
277
return gdev_prn_close(pdev);