1 /* Copyright (C) 1990, 1992 Aladdin Enterprises. All rights reserved.
2 Distributed by Free Software Foundation, Inc.
3
4 This file is part of Ghostscript.
5
6 Ghostscript is distributed in the hope that it will be useful, but
7 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
8 to anyone for the consequences of using it or for whether it serves any
9 particular purpose or works at all, unless he says so in writing. Refer
10 to the Ghostscript General Public License for full details.
11
12 Everyone is granted permission to copy, modify and redistribute
13 Ghostscript, but only under the conditions described in the Ghostscript
14 General Public License. A copy of this license is supposed to have been
15 given to you along with Ghostscript so you can know your rights and
16 responsibilities. It should be in a file named COPYING. Among other
17 things, the copyright notice and this notice must be preserved on all
18 copies. */
19
20 /* gdevp201.c */
21 /* NEC PC-PR201 printer driver for Ghostscript */
22 /* modified by m.mori for printers other than pr-201 */
23 /* modified by OkI for hires-98 */
24 /* modified by ASAYAMA Kazunori for Ghostscript version 2.6.1 */
25 #include "gdevprn.h"
26
27 /* There are NEC PC-PR printer paramaters.
28 MODEL DEVICE_NAME X_DPI,Y_DPI HEAD_PINS LF_PITCH
29 PC-PR201 "nec160" 160 24 18
30 PC-PR1000 "nec240" 240 40 20
31 PC-PR150 "nec320" 320 48 18
32 PC-PR1000/4 "nec400" 400 60 18
33 */
34
35 #define WIDTH 80 /* width_10ths, 8" */
36 #define HEIGHT 110 /* height_10ths, 11" */
37
38 enum{PR201, PR1000, PR150, PR1K4};
39
40 static dev_proc_print_page(pr201_print_page);
41
42 /* The device descriptor */
43 gx_device_printer gs_pr201_device =
44 prn_device(prn_std_procs, "pr201",
45 WIDTH,
46 HEIGHT,
47 160,
48 160,
49 0,0,0,0, /* margins */
50 1, pr201_print_page);
51
52 gx_device_printer gs_pr1000_device =
53 prn_device(prn_std_procs, "pr1000",
54 WIDTH,
55 HEIGHT,
56 240,
57 240,
58 0,0,0,0, /* margins */
59 1, pr201_print_page);
60
61 gx_device_printer gs_pr150_device =
62 prn_device(prn_std_procs, "pr150",
63 WIDTH,
64 HEIGHT,
65 320,
66 320,
67 0,0,0,0, /* margins */
68 1, pr201_print_page);
69
70 gx_device_printer gs_pr1000_4_device =
71 prn_device(prn_std_procs, "pr1000_4",
72 WIDTH,
73 HEIGHT,
74 400,
75 400,
76 0,0,0,0, /* margins */
77 1, pr201_print_page);
78
79 /* Transpose a block of 8x8 bits */
80 static int
pr201_transpose_8x8(byte * src,int src_step,byte * dst,int dst_step)81 pr201_transpose_8x8(byte *src, int src_step, byte *dst, int dst_step)
82 {
83 byte mask, s, d0, d1, d2, d3, d4, d5, d6, d7;
84 int i;
85
86 d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = 0;
87
88 for(i=0, mask=0x01; i<8; i++, mask <<= 1) {
89 s = *src;
90 if(s & 0x80) d0 |= mask;
91 if(s & 0x40) d1 |= mask;
92 if(s & 0x20) d2 |= mask;
93 if(s & 0x10) d3 |= mask;
94 if(s & 0x08) d4 |= mask;
95 if(s & 0x04) d5 |= mask;
96 if(s & 0x02) d6 |= mask;
97 if(s & 0x01) d7 |= mask;
98 src += src_step;
99 }
100
101 *dst = d0;
102 *(dst += dst_step) = d1;
103 *(dst += dst_step) = d2;
104 *(dst += dst_step) = d3;
105 *(dst += dst_step) = d4;
106 *(dst += dst_step) = d5;
107 *(dst += dst_step) = d6;
108 *(dst += dst_step) = d7;
109
110 return 0;
111 }
112
113 static int
check_mode(const char * modename)114 check_mode(const char* modename)
115 {
116 if (!strcmp(modename, "pr201"))
117 return PR201;
118 else if (!strcmp(modename, "pr1000"))
119 return PR1000;
120 else if (!strcmp(modename, "pr150"))
121 return PR150;
122 else
123 return PR1K4;
124 }
125
126 /* Send the page to the printer. */
127 static int
pr201_print_page(gx_device_printer * pdev,gp_file * prn_stream)128 pr201_print_page(gx_device_printer *pdev, gp_file *prn_stream)
129 { int line_size;
130 int height;
131 int bits_per_column;
132 int bytes_per_column;
133 int chunk_size;
134 byte *in, *out;
135 int lnum, skip;
136 int head_pins, lr_pitch, x_dpi;
137 int code = 0;
138 byte mask;
139 int endidx = pdev->width>>3;
140
141 switch (check_mode(pdev->dname)){
142 case PR201:
143 head_pins=24; lr_pitch=18; x_dpi=160; break;
144 case PR1000:
145 head_pins=40; lr_pitch=20; x_dpi=240; break;
146 case PR150:
147 head_pins=48; lr_pitch=18; x_dpi=320; break;
148 case PR1K4:
149 default:
150 head_pins=60; lr_pitch=18; x_dpi=400; break;
151 }
152
153 line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
154 height = pdev->height;
155 bits_per_column = head_pins;
156 bytes_per_column = bits_per_column / 8;
157 chunk_size = bits_per_column * line_size;
158
159 in = (byte *)
160 gs_malloc(pdev->memory->non_gc_memory, bits_per_column, line_size, "pr201_print_page(in)");
161 out = (byte *)
162 gs_malloc(pdev->memory->non_gc_memory, bits_per_column, line_size, "pr201_print_page(out)");
163 if(in == 0 || out == 0)
164 return -1;
165
166 if (pdev->width & 7)
167 mask = ~(255>>(pdev->width & 7));
168 else
169 mask = 255, endidx--;
170
171 /* Initialize printer */
172 gp_fputs("\033cl", pdev->file); /* Software Reset */
173 gp_fputs("\033P", pdev->file); /* Proportional Mode */
174 if (check_mode(pdev->dname)==PR150){
175 gp_fprintf(pdev->file, "\034d%d.", x_dpi); /* 320 dpi mode. */
176 }
177 gp_fprintf(pdev->file, "\033T%d" , lr_pitch);
178 /* 18/120 inch per line */
179
180 /* Send Data to printer */
181 lnum = 0;
182 skip = 0;
183 while(lnum < height) {
184 byte *inp, *outp, *out_beg, *out_end, *p;
185 int x, y, num_lines, size, mod, i;
186
187 /* The number of lines to process */
188 if((num_lines = height - lnum) > bits_per_column)
189 num_lines = bits_per_column;
190
191 /* Copy scan lines */
192 for (i = 0, p = in; i < num_lines; i++, p += line_size) {
193 code = gdev_prn_get_bits(pdev, lnum + i, p, NULL);
194 if (code < 0)
195 goto error;
196 p[endidx] &= mask;
197 }
198
199 /* Ensure we have a full stripe of line data */
200 for (; i < bits_per_column; i++, p += line_size) {
201 memset(p, 0, line_size);
202 }
203
204 /* Test for all zero */
205 size = line_size * num_lines;
206 if(in[0] == 0 &&
207 !memcmp((char *)in, (char *)in + 1, size - 1)) {
208 lnum += bits_per_column;
209 skip ++;
210 continue;
211 }
212
213 /* Fill zero */
214 if(num_lines < bits_per_column) {
215 size = line_size * (bits_per_column - num_lines);
216 memset(in + line_size * num_lines, 0, size);
217 }
218 lnum += bits_per_column;
219
220 /* Vertical tab to the appropriate position. */
221 while(skip > 72) {
222 gp_fprintf(pdev->file, "\037%c", 16 + 72);
223 skip -= 72;
224 }
225 if(skip > 0) {
226 gp_fprintf(pdev->file, "\037%c", 16 + skip);
227 }
228
229 /* Transpose in blocks of 8 scan lines. */
230 for(y = 0; y < bytes_per_column; y ++) {
231 inp = in + line_size * 8 * y;
232 outp = out + y;
233 for(x = 0; x < line_size; x ++) {
234 pr201_transpose_8x8(inp, line_size,
235 outp, bytes_per_column);
236 inp ++;
237 outp += bits_per_column;
238 }
239 }
240
241 /* Remove trailing 0s. */
242 out_end = out + chunk_size - 1;
243 while(out_end >= out) {
244 if(*out_end)
245 break;
246 out_end --;
247 }
248 size = (out_end - out) + 1;
249 if((mod = size % bytes_per_column) != 0)
250 out_end += bytes_per_column - mod;
251
252 /* Remove leading 0s. */
253 out_beg = out;
254 while(out_beg <= out_end) {
255 if(*out_beg)
256 break;
257 out_beg ++;
258 }
259 out_beg -= (out_beg - out) % bytes_per_column;
260
261 /* Dot addressing */
262 gp_fprintf(pdev->file, "\033F%04" PRIdSIZE,
263 (out_beg - out) / bytes_per_column);
264
265 /* Dot graphics */
266 size = out_end - out_beg + 1;
267 if (check_mode(pdev->dname)==PR201){
268 gp_fprintf(pdev->file,"\033J%04d", size / bytes_per_column);
269 }else{
270 gp_fprintf(pdev->file,"\034bP,48,%04d.",
271 size / bytes_per_column);
272 }
273 gp_fwrite(out_beg, size, 1, pdev->file);
274
275 /* Carriage Return */
276 gp_fputc('\r', pdev->file);
277 skip = 1;
278 }
279
280 /* Form Feed */
281 gp_fputc('\f',pdev->file);
282 gp_fflush(pdev->file);
283
284 error:
285 gs_free(pdev->memory->non_gc_memory, (char *)out,
286 bits_per_column, line_size, "pr201_print_page(out)");
287 gs_free(pdev->memory->non_gc_memory, (char *)in,
288 bits_per_column, line_size, "pr201_print_page(in)");
289
290 return code;
291 }
292