xref: /plan9/sys/src/cmd/gs/src/gdevcp50.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
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