2 |
- |
1 |
/* Copyright (C) 1997, 1999 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: gdevlj56.c,v 1.7 2005/07/07 16:44:17 stefan Exp $ */
|
|
|
18 |
/* H-P LaserJet 5 & 6 drivers for Ghostscript */
|
|
|
19 |
#include "gdevprn.h"
|
|
|
20 |
#include "stream.h"
|
|
|
21 |
#include "gdevpcl.h"
|
|
|
22 |
#include "gdevpxat.h"
|
|
|
23 |
#include "gdevpxen.h"
|
|
|
24 |
#include "gdevpxop.h"
|
|
|
25 |
#include "gdevpxut.h"
|
|
|
26 |
|
|
|
27 |
/* Define the default resolution. */
|
|
|
28 |
#ifndef X_DPI
|
|
|
29 |
# define X_DPI 600
|
|
|
30 |
#endif
|
|
|
31 |
#ifndef Y_DPI
|
|
|
32 |
# define Y_DPI 600
|
|
|
33 |
#endif
|
|
|
34 |
|
|
|
35 |
/* Define the number of blank lines that make it worthwhile to */
|
|
|
36 |
/* start a new image. */
|
|
|
37 |
#define MIN_SKIP_LINES 2
|
|
|
38 |
|
|
|
39 |
/* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */
|
|
|
40 |
#define W sizeof(word)
|
|
|
41 |
|
|
|
42 |
private dev_proc_open_device(ljet5_open);
|
|
|
43 |
private dev_proc_close_device(ljet5_close);
|
|
|
44 |
private dev_proc_print_page(ljet5_print_page);
|
|
|
45 |
|
|
|
46 |
private const gx_device_procs ljet5_procs =
|
|
|
47 |
prn_procs(ljet5_open, gdev_prn_output_page, ljet5_close);
|
|
|
48 |
|
|
|
49 |
const gx_device_printer gs_lj5mono_device =
|
|
|
50 |
prn_device(ljet5_procs, "lj5mono",
|
|
|
51 |
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
|
|
|
52 |
X_DPI, Y_DPI,
|
|
|
53 |
0, 0, 0, 0,
|
|
|
54 |
1, ljet5_print_page);
|
|
|
55 |
|
|
|
56 |
private const gx_device_procs lj5gray_procs =
|
|
|
57 |
prn_color_procs(ljet5_open, gdev_prn_output_page, ljet5_close,
|
|
|
58 |
gx_default_gray_map_rgb_color,
|
|
|
59 |
gx_default_gray_map_color_rgb);
|
|
|
60 |
|
|
|
61 |
const gx_device_printer gs_lj5gray_device = {
|
|
|
62 |
prn_device_body(gx_device_printer, lj5gray_procs, "lj5gray",
|
|
|
63 |
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
|
|
|
64 |
X_DPI, Y_DPI,
|
|
|
65 |
0, 0, 0, 0,
|
|
|
66 |
1, 8, 255, 0, 256, 1, ljet5_print_page)
|
|
|
67 |
};
|
|
|
68 |
|
|
|
69 |
/* Open the printer, writing the stream header. */
|
|
|
70 |
private int
|
|
|
71 |
ljet5_open(gx_device * pdev)
|
|
|
72 |
{
|
|
|
73 |
int code = gdev_prn_open(pdev);
|
|
|
74 |
|
|
|
75 |
if (code < 0)
|
|
|
76 |
return code;
|
|
|
77 |
code = gdev_prn_open_printer(pdev, true);
|
|
|
78 |
if (code < 0)
|
|
|
79 |
return code;
|
|
|
80 |
{
|
|
|
81 |
gx_device_printer *const ppdev = (gx_device_printer *)pdev;
|
|
|
82 |
stream fs;
|
|
|
83 |
stream *const s = &fs;
|
|
|
84 |
byte buf[50]; /* arbitrary */
|
|
|
85 |
|
|
|
86 |
s_init(s, pdev->memory);
|
|
|
87 |
swrite_file(s, ppdev->file, buf, sizeof(buf));
|
|
|
88 |
px_write_file_header(s, pdev);
|
|
|
89 |
sflush(s); /* don't close */
|
|
|
90 |
}
|
|
|
91 |
return 0;
|
|
|
92 |
}
|
|
|
93 |
|
|
|
94 |
/* Close the printer, writing the stream trailer. */
|
|
|
95 |
private int
|
|
|
96 |
ljet5_close(gx_device * pdev)
|
|
|
97 |
{
|
|
|
98 |
gx_device_printer *const ppdev = (gx_device_printer *)pdev;
|
|
|
99 |
int code = gdev_prn_open_printer(pdev, true);
|
|
|
100 |
|
|
|
101 |
if (code < 0)
|
|
|
102 |
return code;
|
|
|
103 |
px_write_file_trailer(ppdev->file);
|
|
|
104 |
return gdev_prn_close(pdev);
|
|
|
105 |
}
|
|
|
106 |
|
|
|
107 |
/* Send the page to the printer. For now, just send the whole image. */
|
|
|
108 |
private int
|
|
|
109 |
ljet5_print_page(gx_device_printer * pdev, FILE * prn_stream)
|
|
|
110 |
{
|
|
|
111 |
gs_memory_t *mem = pdev->memory;
|
|
|
112 |
uint line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
|
|
|
113 |
uint line_size_words = (line_size + W - 1) / W;
|
|
|
114 |
uint out_size = line_size + (line_size / 127) + 1;
|
|
|
115 |
word *line = (word *)gs_alloc_byte_array(mem, line_size_words, W, "ljet5(line)");
|
|
|
116 |
byte *out = gs_alloc_bytes(mem, out_size, "ljet5(out)");
|
|
|
117 |
int code = 0;
|
|
|
118 |
int lnum;
|
|
|
119 |
stream fs;
|
|
|
120 |
stream *const s = &fs;
|
|
|
121 |
byte buf[200]; /* arbitrary */
|
|
|
122 |
|
|
|
123 |
if (line == 0 || out == 0) {
|
|
|
124 |
code = gs_note_error(gs_error_VMerror);
|
|
|
125 |
goto done;
|
|
|
126 |
}
|
|
|
127 |
s_init(s, mem);
|
|
|
128 |
swrite_file(s, prn_stream, buf, sizeof(buf));
|
|
|
129 |
|
|
|
130 |
/* Write the page header. */
|
|
|
131 |
{
|
|
|
132 |
static const byte page_header[] = {
|
|
|
133 |
pxtBeginPage,
|
|
|
134 |
DUSP(0, 0), DA(pxaPoint),
|
|
|
135 |
pxtSetCursor
|
|
|
136 |
};
|
|
|
137 |
static const byte mono_header[] = {
|
|
|
138 |
DUB(eGray), DA(pxaColorSpace),
|
|
|
139 |
DUB(e8Bit), DA(pxaPaletteDepth),
|
|
|
140 |
pxt_ubyte_array, pxt_ubyte, 2, 0xff, 0x00, DA(pxaPaletteData),
|
|
|
141 |
pxtSetColorSpace
|
|
|
142 |
};
|
|
|
143 |
static const byte gray_header[] = {
|
|
|
144 |
DUB(eGray), DA(pxaColorSpace),
|
|
|
145 |
pxtSetColorSpace
|
|
|
146 |
};
|
|
|
147 |
|
|
|
148 |
px_write_page_header(s, (gx_device *)pdev);
|
|
|
149 |
px_write_select_media(s, (gx_device *)pdev, NULL, NULL);
|
|
|
150 |
PX_PUT_LIT(s, page_header);
|
|
|
151 |
if (pdev->color_info.depth == 1)
|
|
|
152 |
PX_PUT_LIT(s, mono_header);
|
|
|
153 |
else
|
|
|
154 |
PX_PUT_LIT(s, gray_header);
|
|
|
155 |
}
|
|
|
156 |
|
|
|
157 |
/* Write the image header. */
|
|
|
158 |
{
|
|
|
159 |
static const byte mono_image_header[] = {
|
|
|
160 |
DA(pxaDestinationSize),
|
|
|
161 |
DUB(eIndexedPixel), DA(pxaColorMapping),
|
|
|
162 |
DUB(e1Bit), DA(pxaColorDepth),
|
|
|
163 |
pxtBeginImage
|
|
|
164 |
};
|
|
|
165 |
static const byte gray_image_header[] = {
|
|
|
166 |
DA(pxaDestinationSize),
|
|
|
167 |
DUB(eDirectPixel), DA(pxaColorMapping),
|
|
|
168 |
DUB(e8Bit), DA(pxaColorDepth),
|
|
|
169 |
pxtBeginImage
|
|
|
170 |
};
|
|
|
171 |
|
|
|
172 |
px_put_us(s, pdev->width);
|
|
|
173 |
px_put_a(s, pxaSourceWidth);
|
|
|
174 |
px_put_us(s, pdev->height);
|
|
|
175 |
px_put_a(s, pxaSourceHeight);
|
|
|
176 |
px_put_usp(s, pdev->width, pdev->height);
|
|
|
177 |
if (pdev->color_info.depth == 1)
|
|
|
178 |
PX_PUT_LIT(s, mono_image_header);
|
|
|
179 |
else
|
|
|
180 |
PX_PUT_LIT(s, gray_image_header);
|
|
|
181 |
}
|
|
|
182 |
|
|
|
183 |
/* Write the image data, compressing each line. */
|
|
|
184 |
for (lnum = 0; lnum < pdev->height; ++lnum) {
|
|
|
185 |
int ncompr;
|
|
|
186 |
static const byte line_header[] = {
|
|
|
187 |
DA(pxaStartLine),
|
|
|
188 |
DUS(1), DA(pxaBlockHeight),
|
|
|
189 |
DUB(eRLECompression), DA(pxaCompressMode),
|
|
|
190 |
pxtReadImage
|
|
|
191 |
};
|
|
|
192 |
|
|
|
193 |
code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *) line, line_size);
|
|
|
194 |
if (code < 0)
|
|
|
195 |
goto fin;
|
|
|
196 |
px_put_us(s, lnum);
|
|
|
197 |
PX_PUT_LIT(s, line_header);
|
|
|
198 |
ncompr = gdev_pcl_mode2compress_padded(line, line + line_size_words,
|
|
|
199 |
out, true);
|
|
|
200 |
px_put_data_length(s, ncompr);
|
|
|
201 |
px_put_bytes(s, out, ncompr);
|
|
|
202 |
}
|
|
|
203 |
|
|
|
204 |
/* Finish up. */
|
|
|
205 |
fin:
|
|
|
206 |
spputc(s, pxtEndImage);
|
|
|
207 |
spputc(s, pxtEndPage);
|
|
|
208 |
sflush(s);
|
|
|
209 |
done:
|
|
|
210 |
gs_free_object(mem, out, "ljet5(out)");
|
|
|
211 |
gs_free_object(mem, line, "ljet5(line)");
|
|
|
212 |
return code;
|
|
|
213 |
}
|