Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/gs/src/gdevadmp.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 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: gdevadmp.c,v 1.6 2004/08/10 13:02:36 stefan Exp $*/
18
/*
19
 * Apple DMP / Imagewriter driver
20
 *
21
 * This is a modification of Mark Wedel's Apple DMP and 
22
 * Jonathan Luckey's Imagewriter II driver to
23
 * support the Imagewriter LQ's higher resolution (320x216):
24
 *      appledmp:  120dpi x  72dpi is still supported (yuck)
25
 *	iwlo:	   160dpi x  72dpi
26
 *	iwhi:	   160dpi x 144dpi
27
 *      iwlq:      320dpi x 216dpi
28
 *
29
 * This is also my first attempt to work with gs. I have not included the LQ's
30
 * ability to print in colour. Perhaps at a later date I will tackle that.
31
 *
32
 * BTW, to get your Imagewriter LQ serial printer to work with a PC, attach it
33
 * with a nullmodem serial cable.
34
 *
35
 * Scott Barker (barkers@cuug.ab.ca)
36
 */
37
 
38
/*
39
 * This is a modification of Mark Wedel's Apple DMP driver to
40
 * support 2 higher resolutions:
41
 *      appledmp:  120dpi x  72dpi is still supported (yuck)
42
 *	iwlo:	   160dpi x  72dpi
43
 *	iwhi:	   160dpi x 144dpi
44
 *
45
 * The Imagewriter II is a bit odd.  In pinfeed mode, it thinks its
46
 * First line is 1 inch from the top of the page. If you set the top
47
 * form so that it starts printing at the top of the page, and print
48
 * to near the bottom, it thinks it has run onto the next page and
49
 * the formfeed will skip a whole page.  As a work around, I reverse
50
 * the paper about a 1.5 inches at the end of the page before the
51
 * formfeed to make it think its on the 'right' page.  bah. hack!
52
 * 
53
 * This is  my first attempt to work with gs, so your milage may vary
54
 *
55
 * Jonathan Luckey (luckey@rtfm.mlb.fl.us)
56
 */
57
 
58
/* This is a bare bones driver I developed for my apple Dot Matrix Printer.
59
 * This code originally was from the epson driver, but I removed a lot
60
 * of stuff that was not needed.
61
 *
62
 * The Dot Matrix Printer was a predecessor to the apple Imagewriter.  Its
63
 * main difference being that it was parallel.
64
 *
65
 * This code should work fine on Imagewriters, as they have a superset
66
 * of commands compared to the DMP printer.
67
 *
68
 * This driver does not produce the smalles output files possible.  To
69
 * do that, it should look through the output strings and find repeat
70
 * occurances of characters, and use the escape sequence that allows
71
 * printing repeat sequences.  However, as I see it, this the limiting
72
 * factor in printing is not transmission speed to the printer itself,
73
 * but rather, how fast the print head can move.  This is assuming the
74
 * printer is set up with a reasonable speed (9600 bps)
75
 *
76
 * WHAT THE CODE DOES AND DOES NOT DO:
77
 *
78
 * To print out images, it sets the printer for unidirection printing
79
 * and 15 cpi (120 dpi). IT sets line feed to 1/9 of an inch (72 dpi).
80
 * When finished, it sets things back to bidirection print, 1/8" line
81
 * feeds, and 12 cpi.  There does not appear to be a way to reset
82
 * things to initial values.
83
 *
84
 * This code does not set for 8 bit characters (which is required). It
85
 * also assumes that carriage return/newline is needed, and not just
86
 * carriage return.  These are all switch settings on the DMP, and
87
 * I have configured them for 8 bit data and cr only.
88
 *
89
 * You can search for the strings Init and Reset to find the strings
90
 * that set up the printer and clear things when finished, and change
91
 * them to meet your needs.
92
 *
93
 * Also, you need to make sure that the printer daemon (assuming unix)
94
 * doesn't change the data as it is being printed.  I have set my
95
 * printcap file (sunos 4.1.1) with the string:
96
 * ms=pass8,-opost
97
 * and it works fine.
98
 *
99
 * Feel free to improve this code if you want.  However, please make
100
 * sure that the old DMP will still be supported by any changes.  This
101
 * may mean making an imagewriter device, and just copying this file
102
 * to something like gdevimage.c.
103
 *
104
 * The limiting factor of the DMP is the vertical resolution.  However, I
105
 * see no way to do anything about this.  Horizontal resolution could
106
 * be increased by using 17 cpi (136 dpi).  I believe the Imagewriter
107
 * supports 24 cpi (192 dpi).  However, the higher dpi, the slower
108
 * the printing.
109
 *
110
 * Dot Matrix Code by Mark Wedel (master@cats.ucsc.edu)
111
 */
112
 
113
 
114
#include "gdevprn.h"
115
 
116
/* The device descriptors */
117
private dev_proc_print_page(dmp_print_page);
118
 
119
/* Standard DMP device */
120
const gx_device_printer far_data gs_appledmp_device =
121
prn_device(prn_std_procs, "appledmp",
122
	85,				/* width_10ths, 8.5" */
123
	110,				/* height_10ths, 11" */
124
	120, 72,			/* X_DPI, Y_DPI */
125
	0, 0.5, 0.5, 0,		/* margins */
126
	1, dmp_print_page);
127
 
128
 
129
/*  lowrez Imagewriter device */
130
const gx_device_printer far_data gs_iwlo_device =
131
prn_device(prn_std_procs, "iwlo",
132
	85,				/* width_10ths, 8.5" */
133
	110,				/* height_10ths, 11" */
134
	160, 72,			/* X_DPI, Y_DPI */
135
	0, 0.5, 0.5, 0,		/* margins */
136
	1, dmp_print_page);
137
 
138
 
139
/*  hirez Imagewriter device */
140
const gx_device_printer far_data gs_iwhi_device =
141
prn_device(prn_std_procs, "iwhi",
142
	85,				/* width_10ths, 8.5" */
143
	110,				/* height_10ths, 11" */
144
	160, 144,			/* X_DPI, Y_DPI */
145
	0, 0.5, 0.5, 0,		/* margins */
146
	1, dmp_print_page);
147
 
148
 
149
/* LQ hirez Imagewriter device */
150
const gx_device_printer far_data gs_iwlq_device =
151
prn_device(prn_std_procs, "iwlq",
152
	85,				/* width_10ths, 8.5" */
153
	110,				/* height_10ths, 11" */
154
	320, 216,
155
	0, 0, 0.5, 0,		/* margins */
156
	1, dmp_print_page);
157
 
158
 
159
/* ------ Internal routines ------ */
160
 
161
#define DMP 1
162
#define IWLO 2
163
#define IWHI 3
164
#define IWLQ 4
165
 
166
/* Send the page to the printer. */
167
private int
168
dmp_print_page(gx_device_printer *pdev, FILE *prn_stream)
169
{	
170
	int dev_type;
171
 
172
	int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
173
	/* Note that in_size is a multiple of 8. */
174
	int in_size = line_size * 8;
175
 
176
	byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "dmp_print_page(buf1)");
177
	byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "dmp_print_page(buf2)");
178
	byte *prn = (byte *)gs_malloc(pdev->memory, 3*in_size, 1, "dmp_print_page(prn)");
179
 
180
	byte *in = buf1;
181
	byte *out = buf2;
182
	int lnum = 0;
183
 
184
	/* Check allocations */
185
	if ( buf1 == 0 || buf2 == 0 || prn == 0 )
186
	{
187
		if ( buf1 ) 
188
			gs_free(pdev->memory, (char *)buf1, in_size, 1,
189
			"dmp_print_page(buf1)");
190
		if ( buf2 ) 
191
			gs_free(pdev->memory, (char *)buf2, in_size, 1,
192
			"dmp_print_page(buf2)");
193
		if ( prn ) 
194
			gs_free(pdev->memory, (char *)prn, in_size, 1,
195
			"dmp_print_page(prn)");
196
		return_error(gs_error_VMerror);
197
	}
198
 
199
	if ( pdev->y_pixels_per_inch == 216 )
200
		dev_type = IWLQ;
201
	else if ( pdev->y_pixels_per_inch == 144 )
202
		dev_type = IWHI;
203
	else if ( pdev->x_pixels_per_inch == 160 )
204
		dev_type = IWLO;
205
	else
206
		dev_type = DMP;
207
 
208
	/* Initialize the printer and reset the margins. */
209
 
210
	fputs("\r\n\033>\033T16", prn_stream);
211
 
212
	switch(dev_type)
213
	{
214
	case IWLQ:
215
		fputs("\033P\033a3", prn_stream);
216
		break;
217
	case IWHI:
218
	case IWLO:
219
		fputs("\033P", prn_stream);
220
		break;
221
	case DMP: 
222
	default:
223
		fputs("\033q", prn_stream);
224
		break;
225
	}
226
 
227
	/* Print lines of graphics */
228
	while ( lnum < pdev->height )
229
	{	
230
		byte *inp;
231
		byte *in_end;
232
		byte *out_end;
233
		int lcnt,ltmp;
234
		int count, passes;
235
		byte *prn_blk, *prn_end, *prn_tmp;
236
 
237
/* The apple DMP printer seems to be odd in that the bit order on
238
 * each line is reverse what might be expected.  Meaning, an
239
 * underscore would be done as a series of 0x80, while on overscore
240
 * would be done as a series of 0x01.  So we get each
241
 * scan line in reverse order.
242
 */
243
 
244
		switch (dev_type)
245
		{
246
		case IWLQ: passes = 3; break;
247
		case IWHI: passes = 2; break;
248
		case IWLO:
249
		case DMP:
250
		default: passes = 1; break;
251
		}
252
 
253
		for (count = 0; count < passes; count++)
254
		{
255
			for (lcnt=0; lcnt<8; lcnt++)
256
			{
257
				switch(dev_type)
258
				{
259
				case IWLQ: ltmp = lcnt + 8*count; break;
260
				case IWHI: ltmp = 2*lcnt + count; break;
261
				case IWLO:
262
				case DMP:
263
				default: ltmp = lcnt; break;
264
				}
265
 
266
				if ((lnum+ltmp)>pdev->height) 
267
					memset(in+lcnt*line_size,0,line_size);
268
				else
269
					gdev_prn_copy_scan_lines(pdev,
270
					lnum+ltmp, in + line_size*(7 - lcnt),
271
					line_size);
272
			}
273
 
274
			out_end = out;
275
			inp = in;
276
			in_end = inp + line_size;
277
			for ( ; inp < in_end; inp++, out_end += 8 )
278
			{
279
				gdev_prn_transpose_8x8(inp, line_size,
280
				out_end, 1);
281
			}
282
 
283
			out_end = out;
284
 
285
			switch (dev_type)
286
			{
287
			case IWLQ: prn_end = prn + count; break;
288
			case IWHI: prn_end = prn + in_size*count; break;
289
			case IWLO:
290
			case DMP:
291
			default: prn_end = prn; break;
292
			}
293
 
294
			while ( (int)(out_end-out) < in_size)
295
			{
296
				*prn_end = *(out_end++);
297
				if ((dev_type) == IWLQ) prn_end += 3;
298
				else prn_end++;
299
			}
300
		}
301
 
302
		switch (dev_type)
303
		{
304
		case IWLQ:
305
			prn_blk = prn;
306
			prn_end = prn_blk + in_size * 3;
307
			while (prn_end > prn && prn_end[-1] == 0 &&
308
				prn_end[-2] == 0 && prn_end[-3] == 0)
309
			{
310
				prn_end -= 3;
311
			}
312
			while (prn_blk < prn_end && prn_blk[0] == 0 &&
313
				prn_blk[1] == 0 && prn_blk[2] == 0)
314
			{
315
				prn_blk += 3;
316
			}
317
			if (prn_end != prn_blk)
318
			{
319
				if ((prn_blk - prn) > 7)
320
					fprintf(prn_stream,"\033U%04d%c%c%c",
321
						(int)((prn_blk - prn)/3),
322
						0, 0, 0);
323
				else
324
					prn_blk = prn;
325
				fprintf(prn_stream,"\033C%04d",
326
					(int)((prn_end - prn_blk)/3));
327
				fwrite(prn_blk, 1, (int)(prn_end - prn_blk),
328
					prn_stream);
329
		        }
330
			break;
331
		case IWHI:
332
			for (count = 0; count < 2; count++)
333
			{
334
				prn_blk = prn_tmp = prn + in_size*count;
335
				prn_end = prn_blk + in_size;
336
				while (prn_end > prn_blk && prn_end[-1] == 0)
337
					prn_end--;
338
				while (prn_blk < prn_end && prn_blk[0] == 0)
339
					prn_blk++;
340
				if (prn_end != prn_blk)
341
				{
342
					if ((prn_blk - prn_tmp) > 7)
343
						fprintf(prn_stream,
344
							"\033V%04d%c",
345
							(int)(prn_blk-prn_tmp),
346
							 0);
347
					else
348
						prn_blk = prn_tmp;
349
					fprintf(prn_stream,"\033G%04d",
350
						(int)(prn_end - prn_blk));
351
					fwrite(prn_blk, 1,
352
						(int)(prn_end - prn_blk),
353
						prn_stream);
354
				}
355
				if (!count) fputs("\033T01\r\n",prn_stream);
356
			}
357
			fputs("\033T15",prn_stream);
358
			break;
359
		case IWLO:
360
		case DMP:
361
		default:
362
			prn_blk = prn;
363
			prn_end = prn_blk + in_size;
364
			while (prn_end > prn_blk && prn_end[-1] == 0)
365
				prn_end--;
366
			while (prn_blk < prn_end && prn_blk[0] == 0)
367
				prn_blk++;
368
			if (prn_end != prn_blk)
369
			{
370
				if ((prn_blk - prn) > 7)
371
					fprintf(prn_stream,"\033V%04d%c",
372
						(int)(prn_blk - prn), 0);
373
				else
374
					prn_blk = prn;
375
				fprintf(prn_stream,"\033G%04d",
376
					(int)(prn_end - prn_blk));
377
				fwrite(prn_blk, 1, (int)(prn_end - prn_blk),
378
					prn_stream);
379
			}
380
			break;
381
		}
382
 
383
		fputs("\r\n",prn_stream);
384
 
385
		switch (dev_type)
386
		{
387
			case IWLQ: lnum += 24 ; break;
388
			case IWHI: lnum += 16 ; break;
389
			case IWLO:
390
			case DMP:
391
			default: lnum += 8 ; break;
392
		}
393
	}
394
 
395
	/* ImageWriter will skip a whole page if too close to end */
396
	/* so skip back more than an inch */
397
	if ( !(dev_type == DMP) )
398
		fputs("\033T99\n\n\033r\n\n\n\n\033f", prn_stream);
399
 
400
	/* Formfeed and Reset printer */
401
	fputs("\033T16\f\033<\033B\033E", prn_stream);
402
	fflush(prn_stream);
403
 
404
	gs_free(pdev->memory, (char *)prn, in_size, 1, "dmp_print_page(prn)");
405
	gs_free(pdev->memory, (char *)buf2, in_size, 1, "dmp_print_page(buf2)");
406
	gs_free(pdev->memory, (char *)buf1, in_size, 1, "dmp_print_page(buf1)");
407
	return 0;
408
}