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: gdevatx.c 8250 2007-09-25 13:31:24Z giles $ */
14
/* Practical Automation ATX-23, -24, and -38 driver */
19
* All of the ATX printers have an unprintable margin of 0.125" at the top
20
* and bottom of the page. They also have unprintable left/right margins:
24
* The code below assumes that coordinates refer only to the *printable*
25
* part of each page. This is wrong and must eventually be changed.
28
/* Define the printer commands. */
29
#define ATX_SET_PAGE_LENGTH "\033f" /* + 2-byte length */
30
#define ATX_VERTICAL_TAB "\033L" /* + 2-byte count */
31
#define ATX_UNCOMPRESSED_DATA "\033d" /* + 2-byte count */
32
#define ATX_COMPRESSED_DATA "\033x" /* + 1-byte word count */
33
#define ATX_END_PAGE "\033e"
35
/* The device descriptors */
36
static dev_proc_print_page(atx23_print_page);
37
static dev_proc_print_page(atx24_print_page);
38
static dev_proc_print_page(atx38_print_page);
40
#define ATX_DEVICE(dname, w10, h10, dpi, lrm, btm, print_page)\
41
prn_device_margins(prn_std_procs, dname, w10, h10, dpi, dpi, 0, 0,\
42
lrm, btm, lrm, btm, 1, print_page)
44
const gx_device_printer gs_atx23_device = /* real width = 576 pixels */
45
ATX_DEVICE("atx23", 28 /* 2.84" */, 35 /* (minimum) */,
46
203, 0.25, 0.125, atx23_print_page);
48
const gx_device_printer gs_atx24_device = /* real width = 832 pixels */
49
ATX_DEVICE("atx24", 41 /* 4.1" */, 35 /* (minimum) */,
50
203, 0.193, 0.125, atx24_print_page);
52
const gx_device_printer gs_atx38_device = /* real width = 2400 pixels */
53
ATX_DEVICE("atx38", 80 /* 8.0" */, 35 /* (minimum) */,
54
300, 0.25, 0.125, atx38_print_page);
56
/* Output a printer command with a 2-byte, little-endian numeric argument. */
58
fput_atx_command(FILE *f, const char *str, int value)
61
fputc((byte)value, f);
62
fputc((byte)(value >> 8), f);
66
* Attempt to compress a scan line of data. in_size and out_size are even.
67
* Return -1 if the compressed data would exceed out_size, otherwise the
68
* size of the compressed data (always even).
70
#define MIN_IN_SIZE_TO_COMPRESS 50
71
#define MAX_COMPRESSED_SEGMENT_PAIRS 127
72
#define MAX_UNCOMPRESSED_SEGMENT_PAIRS 255
73
#define COMPRESSED_SEGMENT_COMMAND 0x80 /* + # of repeated pairs */
74
#define UNCOMPRESSED_SEGMENT_COMMAND 0x7f /* followed by # of pairs */
76
atx_compress(const byte *in_buf, int in_size, byte *out_buf, int out_size)
78
const byte *const in_end = in_buf + in_size;
79
byte *const out_end = out_buf + out_size;
80
const byte *in = in_buf;
85
if (in_size < MIN_IN_SIZE_TO_COMPRESS)
86
return -1; /* not worth compressing */
88
/* Start a new segment. */
90
if (in == in_end) /* end of input data */
92
if (out == out_end) /* output buffer full */
96
if (in[1] == in[0]) { /* start compressed segment */
97
/* out[-2] will be compressed segment command */
100
goto Scan_Compressed_Pair;
101
} else { /* start uncompressed segment */
102
out[-2] = UNCOMPRESSED_SEGMENT_COMMAND;
103
/* out[-1] will be pair count */
105
goto Scan_Uncompressed_Pair;
108
/* Scan compressed data. */
110
if (pair_count == MAX_COMPRESSED_SEGMENT_PAIRS ||
111
in == in_end || in[0] != in[-1] || in[1] != in[0]
112
) { /* end the segment */
113
out_command[0] = COMPRESSED_SEGMENT_COMMAND + pair_count;
117
Scan_Compressed_Pair:
119
goto Scan_Compressed;
121
/* Scan uncompressed data. */
123
if (pair_count == MAX_UNCOMPRESSED_SEGMENT_PAIRS ||
124
in == in_end || in[1] == in[0]
125
) { /* end the segment */
126
out_command[1] = pair_count;
129
Scan_Uncompressed_Pair:
130
if (out == out_end) /* output buffer full */
132
out[0] = in[0], out[1] = in[1];
136
goto Scan_Uncompressed;
140
/* Send the page to the printer. */
142
atx_print_page(gx_device_printer *pdev, FILE *f, int max_width_bytes)
145
* The page length command uses 16 bits to represent the length in
146
* units of 0.01", so the maximum representable page length is
147
* 655.35", including the unprintable top and bottom margins.
148
* Compute the maximum height of the printable area in pixels.
150
float top_bottom_skip = (pdev->HWMargins[1] + pdev->HWMargins[3]) / 72.0;
151
int max_height = (int)(pdev->HWResolution[1] * 655 - top_bottom_skip);
152
int height = min(pdev->height, max_height);
153
int page_length_100ths =
154
(int)ceil((height / pdev->HWResolution[1] + top_bottom_skip) * 100);
155
gs_memory_t *mem = pdev->memory;
156
int raster = gx_device_raster((gx_device *)pdev, true);
159
* ATX_COMPRESSED_DATA only takes a 1-byte (word) count.
160
* Thus no compressed scan line can take more than 510 bytes.
162
int compressed_raster = min(raster / 2, 510); /* require 50% compression */
164
int blank_lines, lnum;
167
/* Enforce a minimum 3" page length. */
168
if (page_length_100ths < 300)
169
page_length_100ths = 300;
170
buf = gs_alloc_bytes(mem, raster, "atx_print_page(buf)");
171
compressed = gs_alloc_bytes(mem, compressed_raster,
172
"atx_print_page(compressed)");
173
if (buf == 0 || compressed == 0) {
174
code = gs_note_error(gs_error_VMerror);
177
fput_atx_command(f, ATX_SET_PAGE_LENGTH, page_length_100ths);
178
for (blank_lines = 0, lnum = 0; lnum < height; ++lnum) {
183
gdev_prn_get_bits(pdev, lnum, buf, &row);
184
/* Find the end of the non-blank data. */
185
for (end = row + raster; end > row && end[-1] == 0 && end[-2] == 0; )
187
if (end == row) { /* blank line */
191
if (blank_lines) { /* skip vertically */
192
fput_atx_command(f, ATX_VERTICAL_TAB, blank_lines + 1);
195
/* Truncate the line to the maximum printable width. */
196
if (end - row > max_width_bytes)
197
end = row + max_width_bytes;
198
count = atx_compress(row, end - row, compressed, compressed_raster);
199
if (count >= 0) { /* compressed line */
201
* Note that since compressed_raster can't exceed 510, count
202
* can't exceed 510 either.
204
fputs(ATX_COMPRESSED_DATA, f);
206
fwrite(compressed, 1, count, f);
207
} else { /* uncompressed line */
208
int num_bytes = end - row;
210
fput_atx_command(f, ATX_UNCOMPRESSED_DATA, num_bytes);
211
fwrite(row, 1, num_bytes, f);
215
#if 0 /**************** MAY NOT BE NEEDED ****************/
216
/* Enforce the minimum page length, and skip any final blank lines. */
218
int paper_length = (int)(pdev->HWResolution[1] * 3 + 0.5);
219
int printed_length = height - blank_lines;
221
if (height > paper_length)
222
paper_length = height;
223
if (printed_length < paper_length)
224
fput_atx_command(f, ATX_VERTICAL_TAB,
225
paper_length - printed_length + 1);
230
fputs(ATX_END_PAGE, f);
233
gs_free_object(mem, compressed, "atx_print_page(compressed)");
234
gs_free_object(mem, buf, "atx_print_page(buf)");
238
/* Print pages with specified maximum pixel widths. */
240
atx23_print_page(gx_device_printer *pdev, FILE *f)
242
return atx_print_page(pdev, f, 576 / 8);
245
atx24_print_page(gx_device_printer *pdev, FILE *f)
247
return atx_print_page(pdev, f, 832 / 8);
250
atx38_print_page(gx_device_printer *pdev, FILE *f)
252
return atx_print_page(pdev, f, 2400 / 8);