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