2 |
- |
1 |
/* Copyright (C) 1989, 1992, 1995 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: gdevepsc.c,v 1.11 2004/08/04 19:36:12 stefan Exp $*/
|
|
|
18 |
/* Epson color dot-matrix printer driver by dave@exlog.com */
|
|
|
19 |
#include "gdevprn.h"
|
|
|
20 |
|
|
|
21 |
/*
|
|
|
22 |
* For 9-pin printers, you may select
|
|
|
23 |
* X_DPI = 60, 120, or 240
|
|
|
24 |
* Y_DPI = 60 or 72
|
|
|
25 |
* For 24-pin printers, you may select
|
|
|
26 |
* X_DPI = 60, 120, 180, 240, or 360
|
|
|
27 |
* Y_DPI = 60, 72, 180, or 216
|
|
|
28 |
* Note that a given printer implements *either* Y_DPI = 60 | 180 *or*
|
|
|
29 |
* Y_DPI = 72 | 216; no attempt is made to check this here.
|
|
|
30 |
* Note that X_DPI = 180 or 360 requires Y_DPI > 100;
|
|
|
31 |
* this isn't checked either. Finally, note that X_DPI=240 and
|
|
|
32 |
* X_DPI=360 are double-density modes requiring two passes to print.
|
|
|
33 |
*
|
|
|
34 |
* The values of X_DPI and Y_DPI may be set at compile time:
|
|
|
35 |
* see gdevs.mak.
|
|
|
36 |
*
|
|
|
37 |
* At some time in the future, we could simulate 24-bit output on
|
|
|
38 |
* 9-pin printers by using fractional vertical positioning;
|
|
|
39 |
* we could even implement an X_DPI=360 mode by using the
|
|
|
40 |
* ESC++ command that spaces vertically in units of 1/360"
|
|
|
41 |
* (not supported on many printers.)
|
|
|
42 |
*/
|
|
|
43 |
|
|
|
44 |
#ifndef X_DPI
|
|
|
45 |
# define X_DPI 180 /* pixels per inch */
|
|
|
46 |
#endif
|
|
|
47 |
#ifndef Y_DPI
|
|
|
48 |
# define Y_DPI 180 /* pixels per inch */
|
|
|
49 |
#endif
|
|
|
50 |
|
|
|
51 |
/*
|
|
|
52 |
** Colors for EPSON LQ-2550.
|
|
|
53 |
**
|
|
|
54 |
** We map VIOLET to BLUE since this is the best we can do.
|
|
|
55 |
*/
|
|
|
56 |
#define BLACK 0
|
|
|
57 |
#define MAGENTA 1
|
|
|
58 |
#define CYAN 2
|
|
|
59 |
#define VIOLET 3
|
|
|
60 |
#define YELLOW 4
|
|
|
61 |
#define RED 5
|
|
|
62 |
#define GREEN 6
|
|
|
63 |
#define WHITE 7
|
|
|
64 |
|
|
|
65 |
/*
|
|
|
66 |
** The offset in this array correspond to
|
|
|
67 |
** the ESC-r n value
|
|
|
68 |
*/
|
|
|
69 |
static char rgb_color[2][2][2] = {
|
|
|
70 |
{{BLACK, VIOLET}, {GREEN, CYAN}},
|
|
|
71 |
{{RED, MAGENTA}, {YELLOW, WHITE}}
|
|
|
72 |
};
|
|
|
73 |
|
|
|
74 |
/* Map an RGB color to a printer color. */
|
|
|
75 |
#define cv_shift (sizeof(gx_color_value) * 8 - 1)
|
|
|
76 |
private gx_color_index
|
|
|
77 |
epson_map_rgb_color(gx_device *dev, const gx_color_value cv[])
|
|
|
78 |
{
|
|
|
79 |
|
|
|
80 |
gx_color_value r = cv[0];
|
|
|
81 |
gx_color_value g = cv[1];
|
|
|
82 |
gx_color_value b = cv[2];
|
|
|
83 |
|
|
|
84 |
if (gx_device_has_color(dev))
|
|
|
85 |
/* use ^7 so WHITE is 0 for internal calculations */
|
|
|
86 |
return (gx_color_index)rgb_color[r >> cv_shift][g >> cv_shift][b >> cv_shift] ^ 7;
|
|
|
87 |
else
|
|
|
88 |
return gx_default_map_rgb_color(dev, cv);
|
|
|
89 |
}
|
|
|
90 |
|
|
|
91 |
/* Map the printer color back to RGB. */
|
|
|
92 |
private int
|
|
|
93 |
epson_map_color_rgb(gx_device *dev, gx_color_index color,
|
|
|
94 |
gx_color_value prgb[3])
|
|
|
95 |
{
|
|
|
96 |
#define c1 gx_max_color_value
|
|
|
97 |
if (gx_device_has_color(dev))
|
|
|
98 |
switch ((ushort)color ^ 7)
|
|
|
99 |
{
|
|
|
100 |
case BLACK:
|
|
|
101 |
prgb[0] = 0; prgb[1] = 0; prgb[2] = 0; break;
|
|
|
102 |
case VIOLET:
|
|
|
103 |
prgb[0] = 0; prgb[1] = 0; prgb[2] = c1; break;
|
|
|
104 |
case GREEN:
|
|
|
105 |
prgb[0] = 0; prgb[1] = c1; prgb[2] = 0; break;
|
|
|
106 |
case CYAN:
|
|
|
107 |
prgb[0] = 0; prgb[1] = c1; prgb[2] = c1; break;
|
|
|
108 |
case RED:
|
|
|
109 |
prgb[0] = c1; prgb[1] = 0; prgb[2] = 0; break;
|
|
|
110 |
case MAGENTA:
|
|
|
111 |
prgb[0] = c1; prgb[1] = 0; prgb[2] = c1; break;
|
|
|
112 |
case YELLOW:
|
|
|
113 |
prgb[0] = c1; prgb[1] = c1; prgb[2] = 0; break;
|
|
|
114 |
case WHITE:
|
|
|
115 |
prgb[0] = c1; prgb[1] = c1; prgb[2] = c1; break;
|
|
|
116 |
}
|
|
|
117 |
else
|
|
|
118 |
return gx_default_map_color_rgb(dev, color, prgb);
|
|
|
119 |
return 0;
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
/* The device descriptor */
|
|
|
123 |
private dev_proc_print_page(epsc_print_page);
|
|
|
124 |
|
|
|
125 |
private gx_device_procs epson_procs =
|
|
|
126 |
prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
|
|
|
127 |
epson_map_rgb_color, epson_map_color_rgb);
|
|
|
128 |
|
|
|
129 |
const gx_device_printer far_data gs_epsonc_device =
|
|
|
130 |
prn_device(epson_procs, "epsonc",
|
|
|
131 |
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
|
|
|
132 |
X_DPI, Y_DPI,
|
|
|
133 |
0, 0, 0.25, 0, /* margins */
|
|
|
134 |
3, epsc_print_page);
|
|
|
135 |
|
|
|
136 |
/* ------ Internal routines ------ */
|
|
|
137 |
|
|
|
138 |
/* Forward references */
|
|
|
139 |
private void epsc_output_run(byte *, int, int, char, FILE *, int);
|
|
|
140 |
|
|
|
141 |
/* Send the page to the printer. */
|
|
|
142 |
#define DD 0x80 /* double density flag */
|
|
|
143 |
private int
|
|
|
144 |
epsc_print_page(gx_device_printer *pdev, FILE *prn_stream)
|
|
|
145 |
{ static int graphics_modes_9[5] =
|
|
|
146 |
{ -1, 0 /*60*/, 1 /*120*/, -1, DD+3 /*240*/
|
|
|
147 |
};
|
|
|
148 |
static int graphics_modes_24[7] =
|
|
|
149 |
{ -1, 32 /*60*/, 33 /*120*/, 39 /*180*/,
|
|
|
150 |
-1, -1, DD+40 /*360*/
|
|
|
151 |
};
|
|
|
152 |
int y_24pin = pdev->y_pixels_per_inch > 72;
|
|
|
153 |
int y_mult = (y_24pin ? 3 : 1);
|
|
|
154 |
int line_size = (pdev->width + 7) >> 3; /* always mono */
|
|
|
155 |
int in_size = line_size * (8 * y_mult);
|
|
|
156 |
byte *in = (byte *)gs_malloc(pdev->memory, in_size+1, 1, "epsc_print_page(in)");
|
|
|
157 |
int out_size = ((pdev->width + 7) & -8) * y_mult;
|
|
|
158 |
byte *out = (byte *)gs_malloc(pdev->memory, out_size+1, 1, "epsc_print_page(out)");
|
|
|
159 |
int x_dpi = (int)pdev->x_pixels_per_inch;
|
|
|
160 |
char start_graphics = (char)
|
|
|
161 |
((y_24pin ? graphics_modes_24 : graphics_modes_9)[x_dpi / 60]);
|
|
|
162 |
int first_pass = (start_graphics & DD ? 1 : 0);
|
|
|
163 |
int last_pass = first_pass * 2;
|
|
|
164 |
int dots_per_space = x_dpi / 10; /* pica space = 1/10" */
|
|
|
165 |
int bytes_per_space = dots_per_space * y_mult;
|
|
|
166 |
int skip = 0, lnum = 0, pass;
|
|
|
167 |
/* declare color buffer and related vars */
|
|
|
168 |
byte *color_in;
|
|
|
169 |
int color_line_size, color_in_size;
|
|
|
170 |
int spare_bits = (pdev->width % 8); /* left over bits to go to margin */
|
|
|
171 |
int whole_bits = pdev->width - spare_bits;
|
|
|
172 |
|
|
|
173 |
/* Check allocations */
|
|
|
174 |
if ( in == 0 || out == 0 )
|
|
|
175 |
{ if ( in ) gs_free(pdev->memory, (char *)in, in_size+1, 1, "epsc_print_page(in)");
|
|
|
176 |
if ( out ) gs_free(pdev->memory, (char *)out, out_size+1, 1, "epsc_print_page(out)");
|
|
|
177 |
return -1;
|
|
|
178 |
}
|
|
|
179 |
|
|
|
180 |
/* Initialize the printer and reset the margins. */
|
|
|
181 |
fwrite("\033@\033P\033l\000\033Q\377\033U\001\r", 1, 14, prn_stream);
|
|
|
182 |
|
|
|
183 |
/* Create color buffer */
|
|
|
184 |
if (gx_device_has_color(pdev))
|
|
|
185 |
{
|
|
|
186 |
color_line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
|
|
|
187 |
color_in_size = color_line_size * (8 * y_mult);
|
|
|
188 |
if((color_in = (byte *)gs_malloc(pdev->memory, color_in_size+1, 1,
|
|
|
189 |
"epsc_print_page(color)")) == 0)
|
|
|
190 |
{
|
|
|
191 |
gs_free(pdev->memory, (char *)in, in_size+1, 1, "epsc_print_page(in)");
|
|
|
192 |
gs_free(pdev->memory, (char *)out, out_size+1, 1, "epsc_print_page(out)");
|
|
|
193 |
return(-1);
|
|
|
194 |
}
|
|
|
195 |
}
|
|
|
196 |
else
|
|
|
197 |
{
|
|
|
198 |
color_in = in;
|
|
|
199 |
color_in_size = in_size;
|
|
|
200 |
color_line_size = line_size;
|
|
|
201 |
}
|
|
|
202 |
|
|
|
203 |
/* Print lines of graphics */
|
|
|
204 |
while ( lnum < pdev->height )
|
|
|
205 |
{
|
|
|
206 |
int lcnt;
|
|
|
207 |
byte *nextcolor = NULL; /* position where next color appears */
|
|
|
208 |
byte *nextmono = NULL; /* position to map next color */
|
|
|
209 |
|
|
|
210 |
/* Copy 1 scan line and test for all zero. */
|
|
|
211 |
gdev_prn_copy_scan_lines(pdev, lnum, color_in, color_line_size);
|
|
|
212 |
|
|
|
213 |
if ( color_in[0] == 0 &&
|
|
|
214 |
!memcmp((char *)color_in, (char *)color_in + 1, color_line_size - 1)
|
|
|
215 |
)
|
|
|
216 |
{ lnum++;
|
|
|
217 |
skip += 3 / y_mult;
|
|
|
218 |
continue;
|
|
|
219 |
}
|
|
|
220 |
|
|
|
221 |
/* Vertical tab to the appropriate position. */
|
|
|
222 |
while ( skip > 255 )
|
|
|
223 |
{ fputs("\033J\377", prn_stream);
|
|
|
224 |
skip -= 255;
|
|
|
225 |
}
|
|
|
226 |
if ( skip )
|
|
|
227 |
fprintf(prn_stream, "\033J%c", skip);
|
|
|
228 |
|
|
|
229 |
/* Copy the rest of the scan lines. */
|
|
|
230 |
lcnt = 1 + gdev_prn_copy_scan_lines(pdev, lnum + 1,
|
|
|
231 |
color_in + color_line_size, color_in_size - color_line_size);
|
|
|
232 |
|
|
|
233 |
if ( lcnt < 8 * y_mult )
|
|
|
234 |
{
|
|
|
235 |
memset((char *)(color_in + lcnt * color_line_size), 0,
|
|
|
236 |
color_in_size - lcnt * color_line_size);
|
|
|
237 |
if (gx_device_has_color(pdev)) /* clear the work buffer */
|
|
|
238 |
memset((char *)(in + lcnt * line_size), 0,
|
|
|
239 |
in_size - lcnt * line_size);
|
|
|
240 |
}
|
|
|
241 |
|
|
|
242 |
/*
|
|
|
243 |
** We need to create a normal epson scan line from our color scan line
|
|
|
244 |
** We do this by setting a bit in the "in" buffer if the pixel byte is set
|
|
|
245 |
** to any color. We then search for any more pixels of that color, setting
|
|
|
246 |
** "in" accordingly. If any other color is found, we save it for the next
|
|
|
247 |
** pass. There may be up to 7 passes.
|
|
|
248 |
** In the future, we should make the passes so as to maximize the
|
|
|
249 |
** life of the color ribbon (i.e. go lightest to darkest).
|
|
|
250 |
*/
|
|
|
251 |
do
|
|
|
252 |
{
|
|
|
253 |
byte *inp = in;
|
|
|
254 |
byte *in_end = in + line_size;
|
|
|
255 |
byte *out_end = out;
|
|
|
256 |
byte *out_blk;
|
|
|
257 |
register byte *outp;
|
|
|
258 |
|
|
|
259 |
if (gx_device_has_color(pdev))
|
|
|
260 |
{
|
|
|
261 |
register int i,j;
|
|
|
262 |
register byte *outbuf, *realbuf;
|
|
|
263 |
byte current_color;
|
|
|
264 |
int end_next_bits = whole_bits;
|
|
|
265 |
int lastbits;
|
|
|
266 |
|
|
|
267 |
/* Move to the point in the scanline that has a new color */
|
|
|
268 |
if (nextcolor)
|
|
|
269 |
{
|
|
|
270 |
realbuf = nextcolor;
|
|
|
271 |
outbuf = nextmono;
|
|
|
272 |
memset((char *)in, 0, (nextmono - in));
|
|
|
273 |
i = nextcolor - color_in;
|
|
|
274 |
nextcolor = NULL;
|
|
|
275 |
end_next_bits = (i / color_line_size) * color_line_size
|
|
|
276 |
+ whole_bits;
|
|
|
277 |
}
|
|
|
278 |
else
|
|
|
279 |
{
|
|
|
280 |
i = 0;
|
|
|
281 |
realbuf = color_in;
|
|
|
282 |
outbuf = in;
|
|
|
283 |
nextcolor = NULL;
|
|
|
284 |
}
|
|
|
285 |
/* move thru the color buffer, turning on the appropriate
|
|
|
286 |
** bit in the "mono" buffer", setting pointers to the next
|
|
|
287 |
** color and changing the color output of the epson
|
|
|
288 |
*/
|
|
|
289 |
for (current_color = 0; i <= color_in_size && outbuf < in + in_size; outbuf++)
|
|
|
290 |
{
|
|
|
291 |
/* Remember, line_size is rounded up to next whole byte
|
|
|
292 |
** whereas color_line_size is the proper length
|
|
|
293 |
** We only want to set the proper bits in the last line_size byte.
|
|
|
294 |
*/
|
|
|
295 |
if (spare_bits && i == end_next_bits)
|
|
|
296 |
{
|
|
|
297 |
end_next_bits = whole_bits + i + spare_bits;
|
|
|
298 |
lastbits = 8 - spare_bits;
|
|
|
299 |
}
|
|
|
300 |
else
|
|
|
301 |
lastbits = 0;
|
|
|
302 |
|
|
|
303 |
for (*outbuf = 0, j = 8; --j >= lastbits && i <= color_in_size;
|
|
|
304 |
realbuf++,i++)
|
|
|
305 |
{
|
|
|
306 |
if (*realbuf)
|
|
|
307 |
{
|
|
|
308 |
if (current_color > 0)
|
|
|
309 |
{
|
|
|
310 |
if (*realbuf == current_color)
|
|
|
311 |
{
|
|
|
312 |
*outbuf |= 1 << j;
|
|
|
313 |
*realbuf = 0; /* throw this byte away */
|
|
|
314 |
}
|
|
|
315 |
/* save this location for next pass */
|
|
|
316 |
else if (nextcolor == NULL)
|
|
|
317 |
{
|
|
|
318 |
nextcolor = realbuf - (7 - j);
|
|
|
319 |
nextmono = outbuf;
|
|
|
320 |
}
|
|
|
321 |
}
|
|
|
322 |
else
|
|
|
323 |
{
|
|
|
324 |
*outbuf |= 1 << j;
|
|
|
325 |
current_color = *realbuf; /* set color */
|
|
|
326 |
*realbuf = 0;
|
|
|
327 |
}
|
|
|
328 |
}
|
|
|
329 |
}
|
|
|
330 |
}
|
|
|
331 |
*outbuf = 0; /* zero the end, for safe keeping */
|
|
|
332 |
/* Change color on the EPSON, current_color must be set
|
|
|
333 |
** but lets check anyway
|
|
|
334 |
*/
|
|
|
335 |
if (current_color)
|
|
|
336 |
fprintf(prn_stream,"\033r%d",current_color ^ 7);
|
|
|
337 |
}
|
|
|
338 |
|
|
|
339 |
/* We have to 'transpose' blocks of 8 pixels x 8 lines, */
|
|
|
340 |
/* because that's how the printer wants the data. */
|
|
|
341 |
/* If we are in a 24-pin mode, we have to transpose */
|
|
|
342 |
/* groups of 3 lines at a time. */
|
|
|
343 |
|
|
|
344 |
if ( y_24pin )
|
|
|
345 |
{ for ( ; inp < in_end; inp++, out_end += 24 )
|
|
|
346 |
{ gdev_prn_transpose_8x8(inp, line_size, out_end, 3);
|
|
|
347 |
gdev_prn_transpose_8x8(inp + line_size * 8, line_size, out_end + 1, 3);
|
|
|
348 |
gdev_prn_transpose_8x8(inp + line_size * 16, line_size, out_end + 2, 3);
|
|
|
349 |
}
|
|
|
350 |
/* Remove trailing 0s. */
|
|
|
351 |
while ( out_end > out && out_end[-1] == 0 &&
|
|
|
352 |
out_end[-2] == 0 && out_end[-3] == 0
|
|
|
353 |
)
|
|
|
354 |
out_end -= 3;
|
|
|
355 |
}
|
|
|
356 |
else
|
|
|
357 |
{ for ( ; inp < in_end; inp++, out_end += 8 )
|
|
|
358 |
{ gdev_prn_transpose_8x8(inp, line_size, out_end, 1);
|
|
|
359 |
}
|
|
|
360 |
/* Remove trailing 0s. */
|
|
|
361 |
while ( out_end > out && out_end[-1] == 0 )
|
|
|
362 |
out_end--;
|
|
|
363 |
}
|
|
|
364 |
|
|
|
365 |
for ( pass = first_pass; pass <= last_pass; pass++ )
|
|
|
366 |
{
|
|
|
367 |
for ( out_blk = outp = out; outp < out_end; )
|
|
|
368 |
{ /* Skip a run of leading 0s. */
|
|
|
369 |
/* At least 10 are needed to make tabbing worth it. */
|
|
|
370 |
/* We do everything by 3's to avoid having to make */
|
|
|
371 |
/* different cases for 9- and 24-pin. */
|
|
|
372 |
|
|
|
373 |
if ( *outp == 0 && outp + 12 <= out_end &&
|
|
|
374 |
outp[1] == 0 && outp[2] == 0 &&
|
|
|
375 |
(outp[3] | outp[4] | outp[5]) == 0 &&
|
|
|
376 |
(outp[6] | outp[7] | outp[8]) == 0 &&
|
|
|
377 |
(outp[9] | outp[10] | outp[11]) == 0
|
|
|
378 |
)
|
|
|
379 |
{ byte *zp = outp;
|
|
|
380 |
int tpos;
|
|
|
381 |
byte *newp;
|
|
|
382 |
outp += 12;
|
|
|
383 |
while ( outp + 3 <= out_end && *outp == 0 &&
|
|
|
384 |
outp[1] == 0 && outp[2] == 0
|
|
|
385 |
)
|
|
|
386 |
outp += 3;
|
|
|
387 |
tpos = (outp - out) / bytes_per_space;
|
|
|
388 |
newp = out + tpos * bytes_per_space;
|
|
|
389 |
if ( newp > zp + 10 )
|
|
|
390 |
{ /* Output preceding bit data. */
|
|
|
391 |
if ( zp > out_blk ) /* only false at */
|
|
|
392 |
/* beginning of line */
|
|
|
393 |
epsc_output_run(out_blk, (int)(zp - out_blk),
|
|
|
394 |
y_mult, start_graphics,
|
|
|
395 |
prn_stream, pass);
|
|
|
396 |
/* Tab over to the appropriate position. */
|
|
|
397 |
fprintf(prn_stream, "\033D%c%c\t", tpos, 0);
|
|
|
398 |
out_blk = outp = newp;
|
|
|
399 |
}
|
|
|
400 |
}
|
|
|
401 |
else
|
|
|
402 |
outp += y_mult;
|
|
|
403 |
}
|
|
|
404 |
if ( outp > out_blk )
|
|
|
405 |
epsc_output_run(out_blk, (int)(outp - out_blk),
|
|
|
406 |
y_mult, start_graphics,
|
|
|
407 |
prn_stream, pass);
|
|
|
408 |
|
|
|
409 |
fputc('\r', prn_stream);
|
|
|
410 |
}
|
|
|
411 |
} while (nextcolor);
|
|
|
412 |
skip = 24;
|
|
|
413 |
lnum += 8 * y_mult;
|
|
|
414 |
}
|
|
|
415 |
|
|
|
416 |
/* Eject the page and reinitialize the printer */
|
|
|
417 |
fputs("\f\033@", prn_stream);
|
|
|
418 |
|
|
|
419 |
|
|
|
420 |
gs_free(pdev->memory, (char *)out, out_size+1, 1, "epsc_print_page(out)");
|
|
|
421 |
gs_free(pdev->memory, (char *)in, in_size+1, 1, "epsc_print_page(in)");
|
|
|
422 |
if (gx_device_has_color(pdev))
|
|
|
423 |
gs_free(pdev->memory, (char *)color_in, color_in_size+1, 1, "epsc_print_page(rin)");
|
|
|
424 |
return 0;
|
|
|
425 |
}
|
|
|
426 |
|
|
|
427 |
/* Output a single graphics command. */
|
|
|
428 |
/* pass=0 for all columns, 1 for even columns, 2 for odd columns. */
|
|
|
429 |
private void
|
|
|
430 |
epsc_output_run(byte *data, int count, int y_mult,
|
|
|
431 |
char start_graphics, FILE *prn_stream, int pass)
|
|
|
432 |
{ int xcount = count / y_mult;
|
|
|
433 |
fputc(033, prn_stream);
|
|
|
434 |
if ( !(start_graphics & ~3) )
|
|
|
435 |
{ fputc("KLYZ"[(int)start_graphics], prn_stream);
|
|
|
436 |
}
|
|
|
437 |
else
|
|
|
438 |
{ fputc('*', prn_stream);
|
|
|
439 |
fputc(start_graphics & ~DD, prn_stream);
|
|
|
440 |
}
|
|
|
441 |
fputc(xcount & 0xff, prn_stream);
|
|
|
442 |
fputc(xcount >> 8, prn_stream);
|
|
|
443 |
if ( !pass )
|
|
|
444 |
fwrite((char *)data, 1, count, prn_stream);
|
|
|
445 |
else
|
|
|
446 |
{ /* Only write every other column of y_mult bytes. */
|
|
|
447 |
int which = pass;
|
|
|
448 |
byte *dp = data;
|
|
|
449 |
register int i, j;
|
|
|
450 |
for ( i = 0; i < xcount; i++, which++ )
|
|
|
451 |
for ( j = 0; j < y_mult; j++, dp++ )
|
|
|
452 |
{ putc(((which & 1) ? *dp : 0), prn_stream);
|
|
|
453 |
}
|
|
|
454 |
}
|
|
|
455 |
}
|