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) 1998 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: gdevl31s.c,v 1.5 2004/09/02 21:30:53 giles Exp $ */
18
/*
19
 * H-P LaserJet 3100 driver
20
 *
21
 * This is a driver for use with the H-P LaserJet 3100 Software.
22
 * It requires installed H-P LaserJet 3100 Software to print.
23
 * It can be used with smbclient to print from an UNIX box
24
 * to a LaserJet 3100 printer attached to a MS-Windows box.
25
 *
26
 * Written by Ulrich Schmid, uschmid@mail.hh.provi.de.
27
 */
28
 
29
#include "gdevprn.h"
30
#include "gdevmeds.h"
31
 
32
#define XCORRECTION 0.11
33
#define YCORRECTION 0.12
34
 
35
/* order matters!             0       1        2        3       4      5     6       7           8 */
36
const char *media[10]   =  {"a4", "letter", "legal", "com10", "c5",  "dl", "b5", "monarch", "executive", 0};
37
const int height[2][10] = {{3447,     3240,    4140,    5587, 2644,  5083, 2975,      4387,        3090, 0},
38
			   {6894,     6480,    8280,   11167, 5288, 10159, 5950,      8767,        6180, 0}};
39
const int width[2]      = {2528,
40
			   5056};
41
#define LARGEST_MEDIUM 2 /* legal */
42
 
43
/* These codes correspond to sequences of pixels with the same color.
44
 * After the code for a sequence < 64 pixels the color changes.
45
 * After the code for a sequence with 64 pixels the previous color continues. */ 
46
private struct {
47
	uint bits;
48
	uint length; /* number of valid bits */
49
} code[2][65] =
50
/* White */
51
{{{0x0ac,  8}, {0x038,  6}, {0x00e,  4}, {0x001,  4}, {0x00d,  4}, {0x003,  4}, {0x007,  4}, {0x00f,  4},
52
  {0x019,  5}, {0x005,  5}, {0x01c,  5}, {0x002,  5}, {0x004,  6}, {0x030,  6}, {0x00b,  6}, {0x02b,  6},
53
  {0x015,  6}, {0x035,  6}, {0x072,  7}, {0x018,  7}, {0x008,  7}, {0x074,  7}, {0x060,  7}, {0x010,  7},
54
  {0x00a,  7}, {0x06a,  7}, {0x064,  7}, {0x012,  7}, {0x00c,  7}, {0x040,  8}, {0x0c0,  8}, {0x058,  8},
55
  {0x0d8,  8}, {0x048,  8}, {0x0c8,  8}, {0x028,  8}, {0x0a8,  8}, {0x068,  8}, {0x0e8,  8}, {0x014,  8},
56
  {0x094,  8}, {0x054,  8}, {0x0d4,  8}, {0x034,  8}, {0x0b4,  8}, {0x020,  8}, {0x0a0,  8}, {0x050,  8},
57
  {0x0d0,  8}, {0x04a,  8}, {0x0ca,  8}, {0x02a,  8}, {0x0aa,  8}, {0x024,  8}, {0x0a4,  8}, {0x01a,  8},
58
  {0x09a,  8}, {0x05a,  8}, {0x0da,  8}, {0x052,  8}, {0x0d2,  8}, {0x04c,  8}, {0x0cc,  8}, {0x02c,  8},
59
  {0x01b,  5}},
60
/* Black */
61
 {{0x3b0, 10}, {0x002,  3}, {0x003,  2}, {0x001,  2}, {0x006,  3}, {0x00c,  4}, {0x004,  4}, {0x018,  5},
62
  {0x028,  6}, {0x008,  6}, {0x010,  7}, {0x050,  7}, {0x070,  7}, {0x020,  8}, {0x0e0,  8}, {0x030,  9},
63
  {0x3a0, 10}, {0x060, 10}, {0x040, 10}, {0x730, 11}, {0x0b0, 11}, {0x1b0, 11}, {0x760, 11}, {0x0a0, 11},
64
  {0x740, 11}, {0x0c0, 11}, {0x530, 12}, {0xd30, 12}, {0x330, 12}, {0xb30, 12}, {0x160, 12}, {0x960, 12},
65
  {0x560, 12}, {0xd60, 12}, {0x4b0, 12}, {0xcb0, 12}, {0x2b0, 12}, {0xab0, 12}, {0x6b0, 12}, {0xeb0, 12},
66
  {0x360, 12}, {0xb60, 12}, {0x5b0, 12}, {0xdb0, 12}, {0x2a0, 12}, {0xaa0, 12}, {0x6a0, 12}, {0xea0, 12},
67
  {0x260, 12}, {0xa60, 12}, {0x4a0, 12}, {0xca0, 12}, {0x240, 12}, {0xec0, 12}, {0x1c0, 12}, {0xe40, 12},
68
  {0x140, 12}, {0x1a0, 12}, {0x9a0, 12}, {0xd40, 12}, {0x340, 12}, {0x5a0, 12}, {0x660, 12}, {0xe60, 12},
69
  {0x3c0, 10}}}; 
70
 
71
/* Define the default, maximum resolutions. */
72
#ifndef X_DPI
73
#  define X_DPI 600
74
#endif
75
#ifndef Y_DPI
76
#  define Y_DPI 600
77
#endif
78
 
79
/* The device descriptors */
80
private dev_proc_print_page_copies(lj3100sw_print_page_copies);
81
private dev_proc_close_device(lj3100sw_close);
82
 
83
private gx_device_procs prn_lj3100sw_procs = 
84
    prn_params_procs(gdev_prn_open, gdev_prn_output_page, lj3100sw_close,
85
	     gdev_prn_get_params, gdev_prn_put_params);
86
 
87
/* workaround to emulate the missing prn_device_margins_copies macro */
88
#define gx_default_print_page_copies lj3100sw_print_page_copies
89
gx_device_printer far_data gs_lj3100sw_device =
90
    prn_device_margins/*_copies*/(prn_lj3100sw_procs, "lj3100sw",
91
	     DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
92
	     X_DPI, Y_DPI,
93
	     XCORRECTION, YCORRECTION,
94
	     0.25, 0.2, 0.25, 0.2,
95
	     1, 0 /* lj3100sw_print_page_copies */);
96
#undef gx_default_print_page_copies
97
 
98
#define ppdev ((gx_device_printer *)pdev)
99
 
100
#define BUFFERSIZE 0x1000
101
 
102
private void
103
lj3100sw_output_section_header(FILE *prn_stream, int type, int arg1, int arg2)
104
{
105
	fputc(type      & 0xff, prn_stream);
106
	fputc(type >> 8 & 0xff, prn_stream);
107
	fputc(arg1      & 0xff, prn_stream);
108
	fputc(arg1 >> 8 & 0xff, prn_stream);
109
	fputc(arg2      & 0xff, prn_stream);
110
	fputc(arg2 >> 8 & 0xff, prn_stream);
111
}
112
 
113
private void
114
lj3100sw_flush_buffer(FILE *prn_stream, char *buffer, char **pptr)
115
{
116
	int size = *pptr - buffer;
117
	if (size) {
118
		lj3100sw_output_section_header(prn_stream, 0, size, 0);
119
		fwrite(buffer, 1, size, prn_stream);
120
		*pptr = buffer;
121
	}
122
}
123
 
124
private void
125
lj3100sw_output_data_byte(FILE *prn_stream, char *buffer, char **pptr, int val)
126
{
127
	if (*pptr >= buffer + BUFFERSIZE)
128
		lj3100sw_flush_buffer(prn_stream, buffer, pptr);
129
	*(*pptr)++ = val;
130
}
131
 
132
private void
133
lj3100sw_output_repeated_data_bytes(FILE *prn_stream, char *buffer, char **pptr, int val, int num)
134
{
135
	int size;
136
	while (num) {
137
		if (*pptr >= buffer + BUFFERSIZE)
138
			lj3100sw_flush_buffer(prn_stream, buffer, pptr);
139
		size = min(num, buffer + BUFFERSIZE - *pptr);
140
		memset(*pptr, val, size);
141
		*pptr += size;
142
		num -= size;
143
	}
144
}
145
 
146
private void
147
lj3100sw_output_newline(FILE *prn_stream, char *buffer, char **pptr)
148
{
149
	lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0);
150
	lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0);
151
	lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
152
}
153
 
154
private void
155
lj3100sw_output_empty_line(FILE *prn_stream, char *buffer, char **pptr, bool high_resolution)
156
{
157
	if (high_resolution) {
158
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
159
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x0f);
160
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x78);
161
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0xac);
162
	} else {
163
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x80);
164
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x87);
165
		lj3100sw_output_data_byte(prn_stream, buffer, pptr, 0x0d);
166
	}
167
}
168
 
169
private int
170
lj3100sw_print_page_copies(gx_device_printer *pdev, FILE *prn_stream, int num_copies /* ignored */)
171
{
172
	int i, j;
173
	char buffer[BUFFERSIZE], *ptr = buffer;
174
	int medium_index = select_medium(pdev, media, LARGEST_MEDIUM);
175
	bool high_resolution = (pdev->x_pixels_per_inch > 300);
176
	int printer_height = height[high_resolution ? 1 : 0][medium_index];
177
	int printer_width  = width[high_resolution ? 1 : 0];
178
	int paper_height = pdev->height;
179
	int paper_width  = pdev->width;
180
	int line_size = gdev_prn_raster(pdev);
181
	gs_memory_t *mem = pdev->memory;
182
	byte *in = (byte *)gs_malloc(mem, line_size, 1, "lj3100sw_print_page");
183
	byte *data;
184
	if (in == 0)
185
		return_error(gs_error_VMerror);
186
	if (gdev_prn_file_is_new(pdev)) {
187
		lj3100sw_output_section_header(prn_stream, 1, 0, 0);
188
		lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0x1b, 12);
189
		ptr += sprintf(ptr, "\r\nBD");
190
		lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 5520);
191
		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",
192
			       "NJ",
193
			       "PQ", -1,
194
			       "RE",  high_resolution ? 6 : 2,
195
			       "SL",  printer_width,
196
			       "LM",  0,
197
			       "PS",  medium_index,
198
			       "PC",  0);
199
		lj3100sw_flush_buffer(prn_stream, buffer, &ptr);
200
	}
201
 
202
	lj3100sw_output_section_header(prn_stream, 3, ppdev->NumCopies, 0);
203
	ptr += sprintf(ptr, "%s %d\r\n%s\r\n",
204
		       "CM", 1,
205
		       "PD");
206
	*ptr++ = 0;
207
	lj3100sw_output_newline(prn_stream, buffer, &ptr);
208
 
209
	for (i = 0; i < printer_height; i++) {
210
		if (i < paper_height) {
211
			int color = 0; /* white */
212
			int count = 0;
213
			int bit_index = 0;
214
			uint tmp = 0;
215
			gdev_prn_get_bits(pdev, i, in, &data);
216
			for (j = 0; j <= printer_width; j++) {
217
				int xoffset = (printer_width - paper_width) / 2;
218
				int newcolor = 0;
219
				if (j >= xoffset && j <  xoffset + paper_width)
220
					newcolor = (data[(j - xoffset) / 8] >> (7 - (j - xoffset) % 8)) & 1;
221
				if (j == printer_width)
222
					newcolor = !color; /* force output */
223
				if (newcolor == color)
224
					count++;
225
				else if (count == printer_width && color == 0) /* implies j == printer_width */
226
					lj3100sw_output_empty_line(prn_stream, buffer, &ptr, high_resolution);
227
				else    /* print a sequence of pixels with a uniform color */
228
					while (newcolor != color) {
229
						int size = min(count, 64);
230
						tmp |= code[color][size].bits << bit_index;
231
						bit_index += code[color][size].length;
232
						while (bit_index >= 8)	{
233
							lj3100sw_output_data_byte(prn_stream, buffer, &ptr, tmp & 0xff);
234
							tmp >>= 8;
235
							bit_index -= 8;
236
						}
237
						if (size == 64)
238
							count -= 64;
239
						else {
240
							color = newcolor;
241
							count = 1;
242
						}
243
					}
244
			}
245
			if (bit_index)
246
				lj3100sw_output_data_byte(prn_stream, buffer, &ptr, tmp & 0xff);
247
		}
248
		else
249
			lj3100sw_output_empty_line(prn_stream, buffer, &ptr, high_resolution);
250
		lj3100sw_output_newline(prn_stream, buffer, &ptr);
251
	}
252
 
253
	for (i = 0; i < 3; i++ ) {
254
		lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x00);
255
		lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x08);
256
		lj3100sw_output_data_byte(prn_stream, buffer, &ptr, 0x80);
257
	}
258
	lj3100sw_output_repeated_data_bytes(prn_stream, buffer, &ptr, 0, 520);
259
	lj3100sw_flush_buffer(prn_stream, buffer, &ptr);
260
 
261
	lj3100sw_output_section_header(prn_stream, 4, 0, 0);
262
	for (i = 0; i < 4 * ppdev->NumCopies; i++)
263
		lj3100sw_output_section_header(prn_stream, 54, 0, 0);
264
 
265
	gs_free(mem, (char *)in, line_size, 1, "lj3100sw_print_page");
266
	return 0;
267
}
268
 
269
private int
270
lj3100sw_close(gx_device *pdev)
271
{
272
	int i;
273
	FILE *prn_stream = ((gx_device_printer *)pdev)->file;
274
 
275
	lj3100sw_output_section_header(prn_stream, 0, 4, 0);
276
	fputs("XX\r\n", prn_stream);
277
	for (i = 0; i < 4 * ppdev->NumCopies; i++)
278
		lj3100sw_output_section_header(prn_stream, 54, 0, 0);
279
	lj3100sw_output_section_header(prn_stream, 2, 0, 0);
280
 
281
	return gdev_prn_close(pdev);
282
}