1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 Refer to licensing information at http://www.artifex.com or contact
12 Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16 /* Device to set monochrome mode in PCL */
17 /* This device is one of the 'subclassing' devices, part of a chain or pipeline
18 * of devices, each of which can process some aspect of the graphics methods
19 * before passing them on to the next device in the chain.
20 * In this case, the device simply returns monochrome color_mapping procs
21 * instead of color ones. When we want to go back to color, we just
22 * remove this device.
23 */
24 #include "math_.h"
25 #include "memory_.h"
26 #include "gx.h"
27 #include "gserrors.h"
28 #include "gsparam.h"
29 #include "gxdevice.h"
30 #include "gsdevice.h" /* requires gsmatrix.h */
31 #include "gxdcolor.h" /* for gx_device_black/white */
32 #include "gxiparam.h" /* for image source size */
33 #include "gxgstate.h"
34 #include "gxpaint.h"
35 #include "gxpath.h"
36 #include "gxcpath.h"
37 #include "gxcmap.h" /* color mapping procs */
38 #include "gsstype.h"
39 #include "gdevprn.h"
40 #include "gdevp14.h" /* Needed to patch up the procs after compositor creation */
41 #include "gdevsclass.h"
42 #include "gdevmplt.h"
43 #include "gxdcconv.h" /* for color_rgb_to_gray and color_cmyk_to_gray */
44
45 /* Device procedures, we only need one */
46 static dev_proc_get_color_mapping_procs(pcl_mono_palette_get_color_mapping_procs);
47
48 /* The device prototype */
49 #define MAX_COORD (max_int_in_fixed - 1000)
50 #define MAX_RESOLUTION 4000
51
52 /* GC descriptor */
53 #define public_st_pcl_mono_palette_device() /* in gsdevice.c */\
54 gs_public_st_complex_only(st_pcl_mono_palette_device, gx_device, "PCL_Mono_Palette",\
55 0, pcl_mono_palette_enum_ptrs, pcl_mono_palette_reloc_ptrs, default_subclass_finalize)
56
57 static
58 ENUM_PTRS_WITH(pcl_mono_palette_enum_ptrs, gx_device *dev);
59 return 0; /* default case */
60 case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent));
61 case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child));
62 ENUM_PTRS_END
RELOC_PTRS_WITH(pcl_mono_palette_reloc_ptrs,gx_device * dev)63 static RELOC_PTRS_WITH(pcl_mono_palette_reloc_ptrs, gx_device *dev)
64 {
65 dev->parent = gx_device_reloc_ptr(dev->parent, gcst);
66 dev->child = gx_device_reloc_ptr(dev->child, gcst);
67 }
68 RELOC_PTRS_END
69
70 public_st_pcl_mono_palette_device();
71
72 const
73 gx_device_mplt gs_pcl_mono_palette_device =
74 {
75 /*
76 * Define the device as 8-bit gray scale to avoid computing halftones.
77 */
78 std_device_dci_type_body(gx_device_mplt, 0, "PCL_Mono_Palette", &st_pcl_mono_palette_device,
79 MAX_COORD, MAX_COORD,
80 MAX_RESOLUTION, MAX_RESOLUTION,
81 1, 8, 255, 0, 256, 1),
82 {default_subclass_open_device,
83 default_subclass_get_initial_matrix,
84 default_subclass_sync_output, /* sync_output */
85 default_subclass_output_page,
86 default_subclass_close_device,
87 default_subclass_map_rgb_color,
88 default_subclass_map_color_rgb,
89 default_subclass_fill_rectangle,
90 default_subclass_tile_rectangle, /* tile_rectangle */
91 default_subclass_copy_mono,
92 default_subclass_copy_color,
93 default_subclass_draw_line, /* draw_line */
94 default_subclass_get_bits, /* get_bits */
95 default_subclass_get_params,
96 default_subclass_put_params,
97 default_subclass_map_cmyk_color,
98 default_subclass_get_xfont_procs, /* get_xfont_procs */
99 default_subclass_get_xfont_device, /* get_xfont_device */
100 default_subclass_map_rgb_alpha_color,
101 default_subclass_get_page_device,
102 default_subclass_get_alpha_bits, /* get_alpha_bits */
103 default_subclass_copy_alpha,
104 default_subclass_get_band, /* get_band */
105 default_subclass_copy_rop, /* copy_rop */
106 default_subclass_fill_path,
107 default_subclass_stroke_path,
108 default_subclass_fill_mask,
109 default_subclass_fill_trapezoid,
110 default_subclass_fill_parallelogram,
111 default_subclass_fill_triangle,
112 default_subclass_draw_thin_line,
113 default_subclass_begin_image,
114 default_subclass_image_data, /* image_data */
115 default_subclass_end_image, /* end_image */
116 default_subclass_strip_tile_rectangle,
117 default_subclass_strip_copy_rop,
118 default_subclass_get_clipping_box, /* get_clipping_box */
119 default_subclass_begin_typed_image,
120 default_subclass_get_bits_rectangle, /* get_bits_rectangle */
121 default_subclass_map_color_rgb_alpha,
122 default_subclass_create_compositor,
123 default_subclass_get_hardware_params, /* get_hardware_params */
124 default_subclass_text_begin,
125 default_subclass_finish_copydevice, /* finish_copydevice */
126 default_subclass_begin_transparency_group, /* begin_transparency_group */
127 default_subclass_end_transparency_group, /* end_transparency_group */
128 default_subclass_begin_transparency_mask, /* begin_transparency_mask */
129 default_subclass_end_transparency_mask, /* end_transparency_mask */
130 default_subclass_discard_transparency_layer, /* discard_transparency_layer */
131 pcl_mono_palette_get_color_mapping_procs, /* get_color_mapping_procs */
132 default_subclass_get_color_comp_index, /* get_color_comp_index */
133 default_subclass_encode_color, /* encode_color */
134 default_subclass_decode_color, /* decode_color */
135 default_subclass_pattern_manage, /* pattern_manage */
136 default_subclass_fill_rectangle_hl_color, /* fill_rectangle_hl_color */
137 default_subclass_include_color_space, /* include_color_space */
138 default_subclass_fill_linear_color_scanline, /* fill_linear_color_scanline */
139 default_subclass_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */
140 default_subclass_fill_linear_color_triangle, /* fill_linear_color_triangle */
141 default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */
142 default_subclass_ret_devn_params, /* ret_devn_params */
143 default_subclass_fillpage, /* fillpage */
144 default_subclass_push_transparency_state, /* push_transparency_state */
145 default_subclass_pop_transparency_state, /* pop_transparency_state */
146 default_subclass_put_image, /* put_image */
147 default_subclass_dev_spec_op, /* dev_spec_op */
148 default_subclass_copy_planes, /* copy_planes */
149 default_subclass_get_profile, /* get_profile */
150 default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */
151 default_subclass_strip_copy_rop2,
152 default_subclass_strip_tile_rect_devn,
153 default_subclass_copy_alpha_hl_color,
154 default_subclass_process_page,
155 default_subclass_transform_pixel_region,
156 default_subclass_fill_stroke_path,
157 }
158 };
159
160 #undef MAX_COORD
161 #undef MAX_RESOLUTION
162
163 /* The justification for this device, these 3 procedures map colour values
164 * to gray values
165 */
166 static void
pcl_gray_cs_to_cm(gx_device * dev,frac gray,frac out[])167 pcl_gray_cs_to_cm(gx_device * dev, frac gray, frac out[])
168 {
169 pcl_mono_palette_subclass_data *psubclass_data;
170
171 while(dev && dev->child) {
172 if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0)
173 break;
174 dev = dev->child;
175 };
176
177 if (dev && dev->child) {
178 psubclass_data = dev->subclass_data;
179 /* just pass it along */
180 psubclass_data->device_cm_procs->map_gray(dev, gray, out);
181 } else
182 return;
183 }
184
185 static void
pcl_rgb_cs_to_cm(gx_device * dev,const gs_gstate * pgs,frac r,frac g,frac b,frac out[])186 pcl_rgb_cs_to_cm(gx_device * dev, const gs_gstate * pgs, frac r, frac g,
187 frac b, frac out[])
188 {
189 pcl_mono_palette_subclass_data *psubclass_data;
190 frac gray;
191
192 while(dev && dev->child) {
193 if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0)
194 break;
195 dev = dev->child;
196 };
197
198 if (dev && dev->child) {
199 psubclass_data = dev->subclass_data;
200 gray = color_rgb_to_gray(r, g, b, NULL);
201
202 psubclass_data->device_cm_procs->map_rgb(dev, pgs, gray, gray, gray, out);
203 } else
204 return;
205 }
206
207 static void
pcl_cmyk_cs_to_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])208 pcl_cmyk_cs_to_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
209 {
210 pcl_mono_palette_subclass_data *psubclass_data;
211 frac gray;
212
213 while(dev && dev->child) {
214 if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0)
215 break;
216 dev = dev->child;
217 };
218
219 if (dev && dev->child) {
220 psubclass_data = dev->subclass_data;
221 gray = color_cmyk_to_gray(c, m, y, k, NULL);
222
223 psubclass_data->device_cm_procs->map_cmyk(dev, gray, gray, gray, gray, out);
224 } else
225 return;
226 }
227
pcl_mono_palette_get_color_mapping_procs(const gx_device * dev)228 const gx_cm_color_map_procs *pcl_mono_palette_get_color_mapping_procs(const gx_device *dev)
229 {
230 pcl_mono_palette_subclass_data *psubclass_data = dev->subclass_data;
231
232 if (psubclass_data->device_cm_procs == 0L) {
233 psubclass_data->pcl_mono_procs.map_gray = pcl_gray_cs_to_cm;
234 psubclass_data->pcl_mono_procs.map_rgb = pcl_rgb_cs_to_cm;
235 psubclass_data->pcl_mono_procs.map_cmyk = pcl_cmyk_cs_to_cm;
236 psubclass_data->device_cm_procs = (gx_cm_color_map_procs *)dev_proc(dev->child, get_color_mapping_procs) (dev->child);
237 }
238 return &psubclass_data->pcl_mono_procs;
239 }
240