1 /* Copyright (C) 1999 Norihito Ohmori.
2
3 Ghostscript driver for EPSON ESC/Page 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: gdevespg.c $ */
21 /* EPSON ESC/Page driver for Ghostscript */
22
23 /*
24 Main part of this driver is taked from Hiroshi Narimatsu's
25 Ghostscript driver, epag-3.08.
26 <ftp://ftp.humblesoft.com/pub/epag-3.08.tar.gz>
27 */
28
29 #include "gdevlprn.h"
30 #include "gdevlips.h"
31
32 #define DPI 300
33
34 /* The device descriptors */
35 static dev_proc_open_device(escpage_open);
36 static dev_proc_open_device(lp2000_open);
37 static dev_proc_close_device(escpage_close);
38 static dev_proc_print_page_copies(escpage_print_page_copies);
39 static dev_proc_print_page_copies(lp2000_print_page_copies);
40 static dev_proc_image_out(escpage_image_out);
41
42 static void escpage_printer_initialize(gx_device_printer * pdev, FILE * fp, int);
43 static void escpage_paper_set(gx_device_printer * pdev, FILE * fp);
44
45 static gx_device_procs lp2000_prn_procs =
46 lprn_procs(lp2000_open, gdev_prn_output_page, gdev_prn_close);
47
48 static gx_device_procs escpage_prn_procs =
49 lprn_procs(escpage_open, gdev_prn_output_page, escpage_close);
50
51 gx_device_lprn far_data gs_lp2000_device =
52 lprn_device(gx_device_lprn, lp2000_prn_procs, "lp2000",
53 DPI, DPI, 0.0, 0.0, 0.0, 0.0, 1,
54 lp2000_print_page_copies, escpage_image_out);
55
56 gx_device_lprn far_data gs_escpage_device =
57 lprn_duplex_device(gx_device_lprn, escpage_prn_procs, "escpage",
58 DPI, DPI, 0.0, 0.0, 0.0, 0.0, 1,
59 escpage_print_page_copies, escpage_image_out);
60
61 #define ppdev ((gx_device_printer *)pdev)
62
63 static char *epson_remote_start = "\033\001@EJL \r\n";
64
65 /* Open the printer. */
66 static int
escpage_open(gx_device * pdev)67 escpage_open(gx_device * pdev)
68 {
69 int xdpi = pdev->x_pixels_per_inch;
70 int ydpi = pdev->y_pixels_per_inch;
71
72 /* Resolution Check */
73 if (xdpi != ydpi)
74 return_error(gs_error_rangecheck);
75 if (xdpi < 60 || xdpi > 600)
76 return_error(gs_error_rangecheck);
77
78 return gdev_prn_open(pdev);
79 }
80
81 static int
lp2000_open(gx_device * pdev)82 lp2000_open(gx_device * pdev)
83 {
84 int xdpi = pdev->x_pixels_per_inch;
85 int ydpi = pdev->y_pixels_per_inch;
86
87 /* Resolution Check */
88 if (xdpi != ydpi)
89 return_error(gs_error_rangecheck);
90 if (xdpi < 60 || xdpi > 300)
91 return_error(gs_error_rangecheck);
92
93 return gdev_prn_open(pdev);
94 }
95
96 static int
escpage_close(gx_device * pdev)97 escpage_close(gx_device * pdev)
98 {
99 gdev_prn_open_printer(pdev, 1);
100 if (ppdev->Duplex && (pdev->PageCount & 1)) {
101 fprintf(ppdev->file, "%c0dpsE", GS);
102 }
103 fputs(epson_remote_start, ppdev->file);
104 fputs(epson_remote_start, ppdev->file);
105 return gdev_prn_close(pdev);
106 }
107
108 static int
escpage_print_page_copies(gx_device_printer * pdev,FILE * fp,int num_coipes)109 escpage_print_page_copies(gx_device_printer * pdev, FILE * fp, int num_coipes)
110 {
111 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
112
113 if (pdev->PageCount == 0) {
114 double xDpi = pdev->x_pixels_per_inch;
115
116 /* Goto REMOTE MODE */
117 fputs(epson_remote_start, fp);
118 fprintf(fp, "@EJL SELECT LANGUAGE=ESC/PAGE\r\n");
119
120 /* RIT (Resolution Improvement Technology) Setting */
121 if (lprn->RITOff)
122 fprintf(fp, "@EJL SET RI=OFF\r\n");
123 else
124 fprintf(fp, "@EJL SET RI=ON\r\n");
125
126 /* Resolution Setting */
127 fprintf(fp, "@EJL SET RS=%s\r\n", xDpi > 300 ? "FN" : "QK");
128 fprintf(fp, "@EJL ENTER LANGUAGE=ESC/PAGE\r\n");
129 }
130 return lp2000_print_page_copies(pdev, fp, num_coipes);
131 }
132
133 static int
lp2000_print_page_copies(gx_device_printer * pdev,FILE * fp,int num_coipes)134 lp2000_print_page_copies(gx_device_printer * pdev, FILE * fp, int num_coipes)
135 {
136 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
137 int code = 0;
138 int bpl = gdev_mem_bytes_per_scan_line(pdev);
139 int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
140
141 /* printer initialize */
142 if (pdev->PageCount == 0)
143 escpage_printer_initialize(pdev, fp, num_coipes);
144
145 if (!(lprn->CompBuf = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), bpl * 3 / 2 + 1, maxY, "lp2000_print_page_copies(CompBuf)")))
146 return_error(gs_error_VMerror);
147
148 if (lprn->NegativePrint) {
149 fprintf(fp, "%c1dmG", GS);
150 fprintf(fp, "%c0;0;%d;%d;0rG", GS, pdev->width, pdev->height);
151 fprintf(fp, "%c2owE", GS);
152 }
153 code = lprn_print_image(pdev, fp);
154 if (code < 0)
155 return code;
156
157 gs_free(gs_lib_ctx_get_non_gc_memory_t(), lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "lp2000_print_page_copies(CompBuf)");
158
159 if (pdev->Duplex)
160 fprintf(fp, "%c0dpsE", GS);
161 else
162 fprintf(fp, "\014"); /* eject page */
163 return code;
164 }
165
166 /* Output data */
167 static void
escpage_image_out(gx_device_printer * pdev,FILE * fp,int x,int y,int width,int height)168 escpage_image_out(gx_device_printer * pdev, FILE * fp, int x, int y, int width, int height)
169 {
170 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
171 int Len;
172
173 fprintf(fp, "%c%dY%c%dX", GS, y, GS, x);
174
175 Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
176
177 fprintf(fp, "%c%d;%d;%d;0bi{I", GS, Len,
178 width, height);
179 fwrite(lprn->CompBuf, 1, Len, fp);
180
181 if (lprn->ShowBubble) {
182 fprintf(fp, "%c0dmG", GS);
183 fprintf(fp, "%c%d;%d;%d;%d;0rG", GS,
184 x, y, x + width, y + height);
185 }
186 }
187
188 /* output printer initialize code */
189
190 /* ------ Internal routines ------ */
191
192 static char can_inits[] =
193 {
194 ESC, 'S', ESC, ESC, 'S', 034,
195 ESC, 'z', 0, 0, /* Go to ESC/Page */
196 GS, 'r', 'h', 'E', /* hard reset */
197 GS, '1', 'm', 'm', 'E', /* Page Memory Mode (for LP-3000/7000/7000G) */
198 GS, '3', 'b', 'c', 'I', /* Style of Compression */
199 GS, '0', ';', '0', 'i', 'u', 'E', /* Paper Feed Unit (Auto) */
200 };
201
202 static void
escpage_printer_initialize(gx_device_printer * pdev,FILE * fp,int copies)203 escpage_printer_initialize(gx_device_printer * pdev, FILE * fp, int copies)
204 {
205 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
206 double xDpi, yDpi;
207
208 xDpi = pdev->x_pixels_per_inch;
209 yDpi = pdev->y_pixels_per_inch;
210
211 /* Initialize */
212 fwrite(can_inits, sizeof(can_inits), 1, fp);
213 /* Duplex Setting */
214 if (pdev->Duplex_set > 0) {
215 if (pdev->Duplex) {
216 fprintf(fp, "%c1sdE", GS);
217 if (lprn->Tumble == 0)
218 fprintf(fp, "%c0bdE", GS);
219 else
220 fprintf(fp, "%c1bdE", GS);
221 } else
222 fprintf(fp, "%c0sdE", GS);
223 }
224 /* Set the Size Unit */
225 fprintf(fp, "%c0;%4.2fmuE", GS, 72.0 / xDpi);
226 /* Set the Resolution */
227 fprintf(fp, "%c0;%d;%ddrE", GS, (int)(xDpi + 0.5), (int)(yDpi + 0.5));
228 /* Set the Paper Size */
229 escpage_paper_set(pdev, fp);
230 /* Set the desired number of Copies */
231 fprintf(fp, "%c%dcoO", GS, copies < 256 ? copies : 255);
232 /* Set the Position to (0, 0) */
233 fprintf(fp, "%c0;0loE", GS);
234 }
235
236 typedef struct {
237 int width; /* paper width (unit: point) */
238 int height; /* paper height (unit: point) */
239 int escpage; /* number of papersize in ESC/PAGE */
240 } EpagPaperTable;
241
242 static EpagPaperTable epagPaperTable[] =
243 {
244 {842, 1190, 13}, /* A3 */
245 {595, 842, 14}, /* A4 */
246 {597, 842, 14}, /* A4 (8.3x11.7 inch) */
247 {421, 595, 15}, /* A5 */
248 {297, 421, 16}, /* A6 */
249 {729, 1032, 24}, /* B4 JIS */
250 {516, 729, 25}, /* B5 JIS */
251 {612, 792, 30}, /* Letter */
252 {396, 612, 31}, /* Half Letter */
253 {612, 1008, 32}, /* Legal */
254 {522, 756, 33}, /* Executive */
255 {612, 936, 34}, /* Government Legal */
256 {576, 756, 35}, /* Government Letter */
257 {792, 1224, 36}, /* Ledger */
258 {593, 935, 37}, /* F4 */
259 {284, 419, 38}, /* PostCard */
260 {933, 1369, 72}, /* A3 NOBI */
261 {279, 540, 80}, /* Monarch */
262 {297, 684, 81}, /* Commercial 10 */
263 {312, 624, 90}, /* DL */
264 {459, 649, 91}, /* C5 */
265 {0, 0, -1}, /* Undefined */
266 };
267
268 static void
escpage_paper_set(gx_device_printer * pdev,FILE * fp)269 escpage_paper_set(gx_device_printer * pdev, FILE * fp)
270 {
271 int width, height, w, h, wp, hp, bLandscape;
272 EpagPaperTable *pt;
273
274 width = pdev->MediaSize[0];
275 height = pdev->MediaSize[1];
276
277 if (width < height) {
278 bLandscape = 0;
279 w = width;
280 h = height;
281 wp = width / 72.0 * pdev->x_pixels_per_inch;
282 hp = height / 72.0 * pdev->y_pixels_per_inch;
283 } else {
284 bLandscape = 1;
285 w = height;
286 h = width;
287 wp = height / 72.0 * pdev->y_pixels_per_inch;
288 hp = width / 72.0 * pdev->x_pixels_per_inch;
289 }
290
291 for (pt = epagPaperTable; pt->escpage > 0; pt++)
292 if (pt->width == w && pt->height == h)
293 break;
294
295 fprintf(fp, "%c%d", GS, pt->escpage);
296 if (pt->escpage < 0)
297 fprintf(fp, ";%d;%d", wp, hp);
298 fprintf(fp, "psE");
299
300 fprintf(fp, "%c%dpoE", GS, bLandscape);
301 }
302