1 /* Copyright (C) 1999, 2000 Norihito Ohmori.
2 
3    Ghostscript driver for Ricoh RPDL printer.
4 
5    This software is distributed in the hope that it will be useful, but
6    WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
7    to anyone for the consequences of using it or for whether it serves any
8    particular purpose or works at all, unless he says so in writing.  Refer
9    to the GNU General Public License for full details.
10 
11    Everyone is granted permission to copy, modify and redistribute
12    this software, but only under the conditions described in the GNU
13    General Public License.  A copy of this license is supposed to have been
14    given to you along with this software so you can know your rights and
15    responsibilities.  It should be in a file named COPYING.  Among other
16    things, the copyright notice and this notice must be preserved on all
17    copies.
18  */
19 
20 /*$Id: gdevrpdl.c,v 1.1 2002/10/12 23:24:34 tillkamppeter Exp $ */
21 /* Ricoh RPDL driver for Ghostscript */
22 
23 #include "gdevlprn.h"
24 #include "gdevlips.h"
25 
26 #define DPI 240
27 
28 /* The device descriptors */
29 static dev_proc_open_device(rpdl_open);
30 static dev_proc_close_device(rpdl_close);
31 static dev_proc_print_page_copies(rpdl_print_page_copies);
32 static dev_proc_image_out(rpdl_image_out);
33 static void rpdl_printer_initialize(gx_device_printer * pdev, FILE * prn_stream, int num_copies);
34 static void rpdl_paper_set(gx_device_printer * pdev, FILE * prn_stream);
35 
36 static gx_device_procs rpdl_prn_procs =
37 lprn_procs(rpdl_open, gdev_prn_output_page, rpdl_close);
38 
39 gx_device_lprn far_data gs_rpdl_device =
40 lprn_device(gx_device_lprn, rpdl_prn_procs, "rpdl",
41 	    DPI, DPI, 0.0, 0.0, 0.0, 0.0, 1,
42 	    rpdl_print_page_copies, rpdl_image_out);
43 
44 #define ppdev ((gx_device_printer *)pdev)
45 
46 /* Open the printer. */
47 static int
rpdl_open(gx_device * pdev)48 rpdl_open(gx_device * pdev)
49 {
50     int xdpi = pdev->x_pixels_per_inch;
51     int ydpi = pdev->y_pixels_per_inch;
52 
53     /* Resolution Check */
54     if (xdpi != ydpi)
55 	return_error(gs_error_rangecheck);
56     if (xdpi != 240 && xdpi != 400 && xdpi != 600)
57 	return_error(gs_error_rangecheck);
58 
59     return gdev_prn_open(pdev);
60 }
61 
62 static int
rpdl_close(gx_device * pdev)63 rpdl_close(gx_device * pdev)
64 {
65     gdev_prn_open_printer(pdev, 1);
66     if (ppdev->Duplex && (pdev->PageCount & 1)) {
67 	fprintf(ppdev->file, "\014"); /* Form Feed */
68     }
69     return gdev_prn_close(pdev);
70 }
71 
72 static int
rpdl_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_coipes)73 rpdl_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_coipes)
74 {
75     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
76     int code = 0;
77     int bpl = gdev_mem_bytes_per_scan_line(pdev);
78     int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
79 
80     /* printer initialize */
81     if (pdev->PageCount == 0)
82 	rpdl_printer_initialize(pdev, prn_stream, num_coipes);
83 
84     if (!(lprn->CompBuf = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), bpl * 3 / 2 + 1, maxY, "rpdl_print_page_copies(CompBuf)")))
85 	return_error(gs_error_VMerror);
86 
87     lprn->NegativePrint = false; /* Not Support */
88 
89     code = lprn_print_image(pdev, prn_stream);
90     if (code < 0)
91 	return code;
92 
93     gs_free(gs_lib_ctx_get_non_gc_memory_t(), lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "rpdl_print_page_copies(CompBuf)");
94 
95     fprintf(prn_stream, "\014");	/* Form  Feed */
96 
97     return code;
98 }
99 
100 /* Output data */
101 static void
rpdl_image_out(gx_device_printer * pdev,FILE * prn_stream,int x,int y,int width,int height)102 rpdl_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
103 {
104     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
105     int Len;
106 
107     Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
108 
109     if (Len < width / 8 * height) {
110       if (pdev->x_pixels_per_inch == 240) {
111 	/* Unit Size is 1/720 inch */
112 	fprintf(prn_stream, "\033\022G3,%d,%d,,4,%d,%d,%d@",
113 		width, height, x * 3, y * 3, Len);
114       } else {
115 	fprintf(prn_stream, "\033\022G3,%d,%d,,4,%d,%d,%d@",
116 		width, height, x, y, Len);
117       }
118       fwrite(lprn->CompBuf, 1, Len, prn_stream);
119     } else { /* compression result is bad. So, raw data is used. */
120       if (pdev->x_pixels_per_inch == 240) {
121 	/* Unit Size is 1/720 inch */
122 	fprintf(prn_stream, "\033\022G3,%d,%d,,,%d,%d@",
123 		width, height, x * 3, y * 3);
124 	fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
125       } else {
126 	fprintf(prn_stream, "\033\022G3,%d,%d,,,%d,%d@",
127 		width, height, x, y);
128 	fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
129       }
130     }
131 }
132 
133 /* output printer initialize code */
134 
135 /* ------ Internal routines ------ */
136 
137 static void
rpdl_printer_initialize(gx_device_printer * pdev,FILE * prn_stream,int num_copies)138 rpdl_printer_initialize(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
139 {
140     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
141     int xdpi = (int) pdev->x_pixels_per_inch;
142 
143     /* Initialize */
144     fprintf(prn_stream, "\033\022!@R00\033 "); /* Change to RPDL Mode */
145     fprintf(prn_stream, "\0334"); /* Graphic Mode kaijyo */
146     fprintf(prn_stream, "\033\022YP,2 "); /* Select RPDL Mode */
147     fprintf(prn_stream, "\033\022YB,2 "); /* Printable Area - Maximum */
148     fprintf(prn_stream, "\033\022YK,1 "); /* Left Margin - 0 mm */
149     fprintf(prn_stream, "\033\022YL,1 "); /* Top Margin - 0 mm */
150     fprintf(prn_stream, "\033\022YM,1 "); /* 100 % */
151     fprintf(prn_stream, "\033\022YQ,2 "); /* Page Length - Maximum */
152 
153     /* Paper Size Selection */
154     rpdl_paper_set(pdev, prn_stream);
155 
156     /* Option Setting */
157     /* Duplex Setting */
158     if (pdev->Duplex_set > 0) {
159 	if (pdev->Duplex) {
160 	    fprintf(prn_stream, "\033\02261,");
161 	    if (lprn->Tumble == 0)
162 		fprintf(prn_stream, "\033\022YA01,2 ");
163 	    else
164 		fprintf(prn_stream, "\033\022YA01,1 ");
165 	} else
166 	    fprintf(prn_stream, "\033\02260,");
167     }
168 
169     /* Resolution and Unit Setting */
170     /* Resolution Seting */
171     switch(xdpi) {
172     case 600:
173       fprintf(prn_stream, "\033\022YA04,3 ");
174       break;
175     case 400:
176       fprintf(prn_stream, "\033\022YA04,1 ");
177       break;
178     default: /* 240 dpi */
179       fprintf(prn_stream, "\033\022YA04,2 ");
180       break;
181     }
182 
183     /* Unit Setting */
184     /* Graphics Unit */
185     switch(xdpi) {
186     case 600:
187       fprintf(prn_stream, "\033\022YW,3 ");
188       break;
189     case 400:
190       fprintf(prn_stream, "\033\022YW,1 ");
191       break;
192     default: /* 240 dpi */
193       fprintf(prn_stream, "\033\022YW,2 ");
194       break;
195     }
196 
197     /* Spacing Unit */
198     switch(xdpi) {
199     case 600:
200       fprintf(prn_stream, "\033\022Q5 ");
201       break;
202     case 400:
203       fprintf(prn_stream, "\033\022Q4 ");
204       break;
205     default: /* 240 dpi */
206       fprintf(prn_stream, "\033\022Q0 ");
207       break;
208     }
209 
210     /* Cartecian Unit */
211     switch(xdpi) {
212     case 600:
213       fprintf(prn_stream, "\033\022#4 ");
214       break;
215     case 400:
216       fprintf(prn_stream, "\033\022#2 ");
217       break;
218     }
219 
220     /* Paper Setting */
221     if (pdev->MediaSize[0] > pdev->MediaSize[1])
222       fprintf(prn_stream, "\033\022D2 "); /* landscape */
223     else
224       fprintf(prn_stream, "\033\022D1 "); /* portrait */
225 
226     /* Number of Copies */
227     fprintf(prn_stream, "\033\022N%d ", num_copies);
228 }
229 
230 static void
rpdl_paper_set(gx_device_printer * pdev,FILE * prn_stream)231 rpdl_paper_set(gx_device_printer * pdev, FILE * prn_stream)
232 {
233     int width, height, w, h, wp, hp;
234 
235     width = pdev->MediaSize[0];
236     height = pdev->MediaSize[1];
237 
238     if (width < height) {
239 	w = width;
240 	h = height;
241 	wp = width / 72.0 * pdev->x_pixels_per_inch;
242 	hp = height / 72.0 * pdev->y_pixels_per_inch;
243     } else {
244 	w = height;
245 	h = width;
246 	wp = height / 72.0 * pdev->y_pixels_per_inch;
247 	hp = width / 72.0 * pdev->x_pixels_per_inch;
248     }
249 
250     if (w == 1684 && h == 2380) /* A1 */
251       fprintf(prn_stream, "\033\02251@A1R\033 ");
252     else if (w == 1190 && h == 1684) { /* A2 */
253       fprintf(prn_stream, "\033\02251@A2R\033 ");
254       fprintf(prn_stream, "\033\02251@A2\033 ");
255     } else if (w == 842 && h == 1190) { /* A3 */
256       fprintf(prn_stream, "\033\02251@A3R\033 ");
257       fprintf(prn_stream, "\033\02251@A3\033 ");
258     } else if (w == 595 && h == 842) { /* A4 */
259       fprintf(prn_stream, "\033\02251@A4R\033 ");
260       fprintf(prn_stream, "\033\02251@A4\033 ");
261     } else if (w == 597 && h == 842) { /* A4 */
262       fprintf(prn_stream, "\033\02251@A4R\033 ");
263       fprintf(prn_stream, "\033\02251@A4\033 ");
264     } else if (w == 421 && h == 595) { /* A5 */
265       fprintf(prn_stream, "\033\02251@A5R\033 ");
266       fprintf(prn_stream, "\033\02251@A5\033 ");
267     } else if (w == 297 && h == 421) { /* A6 */
268       fprintf(prn_stream, "\033\02251@A6R\033 ");
269       fprintf(prn_stream, "\033\02251@A6\033 ");
270     } else if (w == 729 && h == 1032) { /* B4 */
271       fprintf(prn_stream, "\033\02251@B4R\033 ");
272       fprintf(prn_stream, "\033\02251@B4\033 ");
273     } else if (w == 516 && h == 729) { /* B5 */
274       fprintf(prn_stream, "\033\02251@B5R\033 ");
275       fprintf(prn_stream, "\033\02251@B5\033 ");
276     } else if (w == 363 && h == 516) { /* B6 */
277       fprintf(prn_stream, "\033\02251@A6R\033 ");
278       fprintf(prn_stream, "\033\02251@A6\033 ");
279     } else if (w == 612 && h == 792) { /* Letter */
280       fprintf(prn_stream, "\033\02251@LTR\033 ");
281       fprintf(prn_stream, "\033\02251@LT\033 ");
282     } else if (w == 612 && h == 1008) { /* Legal */
283       fprintf(prn_stream, "\033\02251@LGR\033 ");
284       fprintf(prn_stream, "\033\02251@LG\033 ");
285     } else if (w == 396 && h == 612) { /* Half Letter */
286       fprintf(prn_stream, "\033\02251@HLR\033 ");
287       fprintf(prn_stream, "\033\02251@HLT\033 ");
288     } else if (w == 792 && h == 1224) { /* Ledger */
289       fprintf(prn_stream, "\033\02251@DLT\033 ");
290       fprintf(prn_stream, "\033\02251@DLR\033 ");
291     } else { /* Free Size (mm) */
292       fprintf(prn_stream, "\033\022?5%d,%d\033 ",
293 	      (int)((w * 25.4) / 72),
294 	      (int)((h * 25.4) / 72));
295     }
296 }
297