1 /* Copyright (C) 1991, 1994, 1996, 1998 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: gdevcp50.c,v 1.7 2005/01/19 00:24:07 dan Exp $*/
18 /* Mitsubishi CP50 color printer driver */
19 #include "gdevprn.h"
20 #define ppdev ((gx_device_printer *)pdev)
21
22 /***
23 *** Note: this driver was contributed by a user. Please contact
24 *** Michael Hu (michael@ximage.com) if you have questions.
25 ***/
26
27 /* The value of X_PIXEL and Y_PIXEL is gained by experiment */
28 #define X_PIXEL 474
29 #define Y_PIXEL 800
30
31 /* The value of FIRST_LINE and LAST_LINE is gained by experiment */
32 /* Note: LAST-LINE - FIRST_LINE + 1 should close to Y_PIXEL */
33 #define FIRST_LINE 140
34 #define LAST_LINE 933
35
36 /* The value of FIRST is gained by experiment */
37 /* There are 60 pixel(RGB) in the right clipped margin */
38 #define FIRST_COLUMN 180
39
40 /* The value of X_DPI and Y_DPI is gained by experiment */
41 #define X_DPI 154 /* pixels per inch */
42 #define Y_DPI 187 /* pixels per inch */
43
44 /* The device descriptor */
45 private dev_proc_print_page(cp50_print_page);
46 private dev_proc_output_page(cp50_output_page);
47
48 private dev_proc_map_rgb_color(cp50_rgb_color);
49 private dev_proc_map_color_rgb(cp50_color_rgb);
50
51 private gx_device_procs cp50_procs =
52 prn_color_procs(gdev_prn_open, cp50_output_page, gdev_prn_close,
53 cp50_rgb_color, cp50_color_rgb);
54
55 const gx_device_printer far_data gs_cp50_device =
56 prn_device(cp50_procs, "cp50",
57 39, /* width_10ths, 100mm */
58 59, /* height_10ths,150mm */
59 X_DPI, Y_DPI,
60 0.39, 0.91, 0.43, 0.75, /* margins */
61 24, cp50_print_page);
62
63 int copies;
64
65 /* ------ Internal routines ------ */
66
67
68 /* Send the page to the printer. */
69 private int
cp50_print_page(gx_device_printer * pdev,FILE * prn_stream)70 cp50_print_page(gx_device_printer *pdev, FILE *prn_stream)
71 {
72 int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
73 byte *out = (byte *)gs_malloc(pdev->memory, line_size, 1, "cp50_print_page(out)");
74 byte *r_plane = (byte *)gs_malloc(pdev->memory, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(r_plane)");
75 byte *g_plane = (byte *)gs_malloc(pdev->memory, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(g_plane)");
76 byte *b_plane = (byte *)gs_malloc(pdev->memory, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(b_plane)");
77 byte *t_plane = (byte *)gs_malloc(pdev->memory, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(t_plane)");
78 int lnum = FIRST_LINE;
79 int last = LAST_LINE;
80 int lines = X_PIXEL;
81 byte hi_lines, lo_lines;
82 byte num_copies;
83 int i,j;
84
85
86 /*fprintf(prn_stream, "%d,%d,%d,", pdev->width, pdev->height, line_size);*/
87
88 /* Check allocations */
89 if ( out == 0 || r_plane == 0 || g_plane == 0 || b_plane == 0 ||
90 t_plane == 0)
91 { if ( out )
92 gs_free(pdev->memory, (char *)out, line_size, 1,
93 "cp50_print_page(out)");
94 if (r_plane)
95 gs_free(pdev->memory, (char *)r_plane, X_PIXEL*Y_PIXEL, 1,
96 "cp50_print_page(r_plane)");
97 if (g_plane)
98 gs_free(pdev->memory, (char *)g_plane, X_PIXEL*Y_PIXEL, 1,
99 "cp50_print_page(g_plane)");
100 if (b_plane)
101 gs_free(pdev->memory, (char *)b_plane, X_PIXEL*Y_PIXEL, 1,
102 "cp50_print_page(b_plane)");
103 if (t_plane)
104 gs_free(pdev->memory, (char *)t_plane, X_PIXEL*Y_PIXEL, 1,
105 "cp50_print_page(t_plane)");
106 return -1;
107 }
108
109 /* set each plane as white */
110 memset(r_plane, -1, X_PIXEL*Y_PIXEL);
111 memset(g_plane, -1, X_PIXEL*Y_PIXEL);
112 memset(b_plane, -1, X_PIXEL*Y_PIXEL);
113 memset(t_plane, -1, X_PIXEL*Y_PIXEL);
114
115 /* Initialize the printer */ /* see programmer manual for CP50 */
116 fprintf(prn_stream,"\033\101");
117 fprintf(prn_stream,"\033\106\010\001");
118 fprintf(prn_stream,"\033\106\010\003");
119
120 /* set number of copies */
121 fprintf(prn_stream,"\033\116");
122 num_copies = copies & 0xFF;
123 fwrite(&num_copies, sizeof(char), 1, prn_stream);
124
125 /* download image */
126 hi_lines = lines >> 8;
127 lo_lines = lines & 0xFF;
128
129 fprintf(prn_stream,"\033\123\062");
130 fwrite(&hi_lines, sizeof(char), 1, prn_stream);
131 fwrite(&lo_lines, sizeof(char), 1, prn_stream);
132 fprintf(prn_stream,"\001"); /* dummy */
133
134 /* Print lines of graphics */
135 while ( lnum <= last )
136 {
137 int i, col;
138 gdev_prn_copy_scan_lines(pdev, lnum, (byte *)out, line_size);
139 /*fwrite(out, sizeof(char), line_size, prn_stream);*/
140 for(i=0; i<X_PIXEL; i++)
141 {
142 col = (lnum-FIRST_LINE) * X_PIXEL + i;
143 r_plane[col] = out[i*3+FIRST_COLUMN];
144 g_plane[col] = out[i*3+1+FIRST_COLUMN];
145 b_plane[col] = out[i*3+2+FIRST_COLUMN];
146 }
147 lnum ++;
148 }
149
150 /* rotate each plane and download it */
151 for(i=0;i<X_PIXEL;i++)
152 for(j=Y_PIXEL-1;j>=0;j--)
153 t_plane[(Y_PIXEL-1-j)+i*Y_PIXEL] = r_plane[i+j*X_PIXEL];
154 fwrite(t_plane, sizeof(char), X_PIXEL*Y_PIXEL, prn_stream);
155
156 for(i=0;i<X_PIXEL;i++)
157 for(j=Y_PIXEL-1;j>=0;j--)
158 t_plane[(Y_PIXEL-1-j)+i*Y_PIXEL] = g_plane[i+j*X_PIXEL];
159 fwrite(t_plane, sizeof(char), X_PIXEL*Y_PIXEL, prn_stream);
160
161 for(i=0;i<X_PIXEL;i++)
162 for(j=Y_PIXEL-1;j>=0;j--)
163 t_plane[(Y_PIXEL-1-j)+i*Y_PIXEL] = b_plane[i+j*X_PIXEL];
164 fwrite(t_plane, sizeof(char), X_PIXEL*Y_PIXEL, prn_stream);
165
166
167 gs_free(pdev->memory, (char *)out, line_size, 1, "cp50_print_page(out)");
168 gs_free(pdev->memory, (char *)r_plane, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(r_plane)");
169 gs_free(pdev->memory, (char *)g_plane, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(g_plane)");
170 gs_free(pdev->memory, (char *)b_plane, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(b_plane)");
171 gs_free(pdev->memory, (char *)t_plane, X_PIXEL*Y_PIXEL, 1, "cp50_print_page(t_plane)");
172
173 return 0;
174 }
175
176 int private
cp50_output_page(gx_device * pdev,int num_copies,int flush)177 cp50_output_page(gx_device *pdev, int num_copies, int flush)
178 { int code, outcode, closecode;
179
180 code = gdev_prn_open_printer(pdev, 1);
181 if ( code < 0 ) return code;
182
183 copies = num_copies; /* using global variable to pass */
184
185 /* Print the accumulated page description. */
186 outcode = (*ppdev->printer_procs.print_page)(ppdev, ppdev->file);
187 if ( code < 0 ) return code;
188
189 closecode = gdev_prn_close_printer(pdev);
190 if ( code < 0 ) return code;
191
192 if ( ppdev->buffer_space ) /* reinitialize clist for writing */
193 code = (*gs_clist_device_procs.output_page)(pdev, num_copies, flush);
194
195 if ( outcode < 0 ) return outcode;
196 if ( closecode < 0 ) return closecode;
197 if ( code < 0 ) return code;
198 return gx_finish_output_page(pdev, num_copies, flush);
199 }
200
201
202 /* 24-bit color mappers (taken from gdevmem2.c). */
203 /* Note that Windows expects RGB values in the order B,G,R. */
204
205 /* Map a r-g-b color to a color index. */
206 private gx_color_index
cp50_rgb_color(gx_device * dev,const gx_color_value cv[])207 cp50_rgb_color(gx_device *dev, const gx_color_value cv[])
208 {
209 gx_color_value red, green, blue;
210
211 red = cv[0]; green = cv[1]; blue = cv[2];
212 return ((ulong)gx_color_value_to_byte(red) << 16)+
213 ((uint)gx_color_value_to_byte(green) << 8) +
214 gx_color_value_to_byte(blue);
215 }
216
217 /* Map a color index to a r-g-b color. */
218 private int
cp50_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])219 cp50_color_rgb(gx_device *dev, gx_color_index color,
220 gx_color_value prgb[3])
221 { prgb[2] = gx_color_value_from_byte(color & 0xff);
222 prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
223 prgb[0] = gx_color_value_from_byte(color >> 16);
224 return 0;
225 }
226