/src/ghostpdl/base/gdevnfwd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 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., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | /* Null and forwarding device implementation */ |
17 | | #include "gx.h" |
18 | | #include "gserrors.h" |
19 | | #include "gxdevice.h" |
20 | | #include "gxcmap.h" |
21 | | #include "memory_.h" |
22 | | #include "gxdevsop.h" |
23 | | |
24 | | /* ---------------- Forwarding procedures ---------------- */ |
25 | | |
26 | | /* Additional finalization for forwarding devices. */ |
27 | | static void |
28 | | gx_device_forward_finalize(gx_device *dev) |
29 | 170M | { |
30 | 170M | gx_device *target = ((gx_device_forward *)dev)->target; |
31 | | |
32 | 170M | ((gx_device_forward *)dev)->target = 0; |
33 | 170M | rc_decrement_only(target, "gx_device_forward_finalize"); |
34 | 170M | } |
35 | | |
36 | | /* Set the target of a forwarding device. */ |
37 | | void |
38 | | gx_device_set_target(gx_device_forward *fdev, gx_device *target) |
39 | 219M | { |
40 | | /* |
41 | | * ****** HACK: if this device doesn't have special finalization yet, |
42 | | * make it decrement the reference count of the target. |
43 | | */ |
44 | 219M | if (target && !fdev->finalize) |
45 | 187M | fdev->finalize = gx_device_forward_finalize; |
46 | 219M | rc_assign(fdev->target, target, "gx_device_set_target"); |
47 | | /* try to initialize to same as target, otherwise UNKNOWN */ |
48 | 219M | fdev->graphics_type_tag = target != NULL ? target->graphics_type_tag : GS_UNKNOWN_TAG; |
49 | 219M | fdev->interpolate_control = target != NULL ? target->interpolate_control : 1; /* the default */ |
50 | 219M | } |
51 | | |
52 | | /* Fill in NULL procedures in a forwarding device procedure record. */ |
53 | | /* We don't fill in: open_device, close_device, or the lowest-level */ |
54 | | /* drawing operations. */ |
55 | | void |
56 | | gx_device_forward_fill_in_procs(register gx_device_forward * dev) |
57 | 1.80M | { |
58 | | /* NOT open_device */ |
59 | 1.80M | fill_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); |
60 | 1.80M | fill_dev_proc(dev, sync_output, gx_forward_sync_output); |
61 | 1.80M | fill_dev_proc(dev, output_page, gx_forward_output_page); |
62 | | /* NOT close_device */ |
63 | 1.80M | fill_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); |
64 | 1.80M | fill_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); |
65 | | /* NOT fill_rectangle */ |
66 | | /* NOT copy_mono */ |
67 | | /* NOT copy_color */ |
68 | 1.80M | fill_dev_proc(dev, get_params, gx_forward_get_params); |
69 | 1.80M | fill_dev_proc(dev, put_params, gx_forward_put_params); |
70 | 1.80M | fill_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); |
71 | 1.80M | fill_dev_proc(dev, get_page_device, gx_forward_get_page_device); |
72 | 1.80M | fill_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); |
73 | | /* NOT copy_alpha */ |
74 | 1.80M | fill_dev_proc(dev, fill_path, gx_forward_fill_path); |
75 | 1.80M | fill_dev_proc(dev, stroke_path, gx_forward_stroke_path); |
76 | 1.80M | fill_dev_proc(dev, fill_mask, gx_forward_fill_mask); |
77 | 1.80M | fill_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid); |
78 | 1.80M | fill_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram); |
79 | 1.80M | fill_dev_proc(dev, fill_triangle, gx_forward_fill_triangle); |
80 | 1.80M | fill_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line); |
81 | | /* NOT strip_tile_rectangle */ |
82 | 1.80M | fill_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); |
83 | 1.80M | fill_dev_proc(dev, begin_typed_image, gx_forward_begin_typed_image); |
84 | 1.80M | fill_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); |
85 | 1.80M | fill_dev_proc(dev, composite, gx_no_composite); |
86 | 1.80M | fill_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); |
87 | 1.80M | fill_dev_proc(dev, text_begin, gx_forward_text_begin); |
88 | 1.80M | fill_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); |
89 | 1.80M | fill_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); |
90 | 1.80M | fill_dev_proc(dev, encode_color, gx_forward_encode_color); |
91 | 1.80M | fill_dev_proc(dev, decode_color, gx_forward_decode_color); |
92 | 1.80M | fill_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); |
93 | 1.80M | fill_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color); |
94 | 1.80M | fill_dev_proc(dev, include_color_space, gx_forward_include_color_space); |
95 | 1.80M | fill_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline); |
96 | 1.80M | fill_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid); |
97 | 1.80M | fill_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle); |
98 | 1.80M | fill_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); |
99 | 1.80M | fill_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); |
100 | 1.80M | fill_dev_proc(dev, fillpage, gx_forward_fillpage); |
101 | 1.80M | fill_dev_proc(dev, put_image, gx_forward_put_image); |
102 | 1.80M | fill_dev_proc(dev, get_profile, gx_forward_get_profile); |
103 | 1.80M | fill_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); |
104 | 1.80M | fill_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2); |
105 | 1.80M | fill_dev_proc(dev, strip_tile_rect_devn, gx_forward_strip_tile_rect_devn); |
106 | 1.80M | fill_dev_proc(dev, strip_tile_rect_devn, gx_forward_strip_tile_rect_devn); |
107 | 1.80M | fill_dev_proc(dev, transform_pixel_region, gx_forward_transform_pixel_region); |
108 | 1.80M | fill_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); |
109 | 1.80M | fill_dev_proc(dev, lock_pattern, gx_forward_lock_pattern); |
110 | 1.80M | gx_device_fill_in_procs((gx_device *) dev); |
111 | 1.80M | } |
112 | | |
113 | | /* Forward the color mapping procedures from a device to its target. */ |
114 | | void |
115 | | gx_device_forward_color_procs(gx_device_forward * dev) |
116 | 161M | { |
117 | 161M | set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); |
118 | 161M | set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); |
119 | 161M | set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); |
120 | 161M | set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); |
121 | 161M | set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); |
122 | 161M | set_dev_proc(dev, encode_color, gx_forward_encode_color); |
123 | 161M | set_dev_proc(dev, decode_color, gx_forward_decode_color); |
124 | 161M | set_dev_proc(dev, get_profile, gx_forward_get_profile); |
125 | | /* Not strictly a color proc, but may affect color encoding */ |
126 | 161M | fill_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); |
127 | 161M | fill_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); |
128 | 161M | } |
129 | | |
130 | | int |
131 | | gx_forward_close_device(gx_device * dev) |
132 | 359 | { |
133 | 359 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
134 | 359 | gx_device *tdev = fdev->target; |
135 | 359 | int code = (tdev == 0) ? gx_default_close_device(dev) |
136 | 359 | : dev_proc(tdev, close_device)(tdev); |
137 | | |
138 | 359 | if (tdev) |
139 | 359 | tdev->is_open = false; /* flag corresponds to the state */ |
140 | 359 | return code; |
141 | 359 | } |
142 | | |
143 | | void |
144 | | gx_forward_get_initial_matrix(gx_device * dev, gs_matrix * pmat) |
145 | 17.3k | { |
146 | 17.3k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
147 | 17.3k | gx_device *tdev = fdev->target; |
148 | | |
149 | 17.3k | if (tdev == 0) |
150 | 0 | gx_default_get_initial_matrix(dev, pmat); |
151 | 17.3k | else |
152 | 17.3k | dev_proc(tdev, get_initial_matrix)(tdev, pmat); |
153 | 17.3k | } |
154 | | |
155 | | int |
156 | | gx_forward_sync_output(gx_device * dev) |
157 | 0 | { |
158 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
159 | 0 | gx_device *tdev = fdev->target; |
160 | |
|
161 | 0 | return (tdev == 0 ? gx_default_sync_output(dev) : |
162 | 0 | dev_proc(tdev, sync_output)(tdev)); |
163 | 0 | } |
164 | | |
165 | | int |
166 | | gx_forward_output_page(gx_device * dev, int num_copies, int flush) |
167 | 0 | { |
168 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
169 | 0 | gx_device *tdev = fdev->target; |
170 | 0 | int code = |
171 | 0 | (tdev == 0 ? gx_default_output_page(dev, num_copies, flush) : |
172 | 0 | dev_proc(tdev, output_page)(tdev, num_copies, flush)); |
173 | |
|
174 | 0 | if (code >= 0 && tdev != 0) |
175 | 0 | dev->PageCount = tdev->PageCount; |
176 | 0 | return code; |
177 | 0 | } |
178 | | |
179 | | gx_color_index |
180 | | gx_forward_map_rgb_color(gx_device * dev, const gx_color_value cv[]) |
181 | 0 | { |
182 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
183 | 0 | gx_device *tdev = fdev->target; |
184 | |
|
185 | 0 | return (tdev == 0 ? gx_error_encode_color(dev, cv) : |
186 | 0 | dev_proc(tdev, map_rgb_color)(tdev, cv)); |
187 | 0 | } |
188 | | |
189 | | int |
190 | | gx_forward_map_color_rgb(gx_device * dev, gx_color_index color, |
191 | | gx_color_value prgb[3]) |
192 | 0 | { |
193 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
194 | 0 | gx_device *tdev = fdev->target; |
195 | |
|
196 | 0 | return (tdev == 0 ? gx_default_map_color_rgb(dev, color, prgb) : |
197 | 0 | dev_proc(tdev, map_color_rgb)(tdev, color, prgb)); |
198 | 0 | } |
199 | | |
200 | | int |
201 | | gx_forward_fill_rectangle(gx_device * dev, int x, int y, int w, int h, |
202 | | gx_color_index color) |
203 | 141M | { |
204 | 141M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
205 | 141M | gx_device *tdev = fdev->target; |
206 | | |
207 | 141M | if (tdev == 0) |
208 | 0 | return_error(gs_error_Fatal); |
209 | 141M | return dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color); |
210 | 141M | } |
211 | | |
212 | | int |
213 | | gx_forward_copy_mono(gx_device * dev, const byte * data, |
214 | | int dx, int raster, gx_bitmap_id id, |
215 | | int x, int y, int w, int h, |
216 | | gx_color_index zero, gx_color_index one) |
217 | 14.8k | { |
218 | 14.8k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
219 | 14.8k | gx_device *tdev = fdev->target; |
220 | | |
221 | 14.8k | if (tdev == 0) |
222 | 0 | return_error(gs_error_Fatal); |
223 | 14.8k | return dev_proc(tdev, copy_mono) |
224 | 14.8k | (tdev, data, dx, raster, id, x, y, w, h, zero, one); |
225 | 14.8k | } |
226 | | |
227 | | int |
228 | | gx_forward_copy_alpha(gx_device * dev, const byte * data, int data_x, |
229 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
230 | | gx_color_index color, int depth) |
231 | 0 | { |
232 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
233 | 0 | gx_device *tdev = fdev->target; |
234 | |
|
235 | 0 | if (tdev == 0) |
236 | 0 | return_error(gs_error_Fatal); |
237 | 0 | return dev_proc(tdev, copy_alpha) |
238 | 0 | (tdev, data, data_x, raster, id, x, y, width, height, color, depth); |
239 | 0 | } |
240 | | |
241 | | int |
242 | | gx_forward_copy_color(gx_device * dev, const byte * data, |
243 | | int dx, int raster, gx_bitmap_id id, |
244 | | int x, int y, int w, int h) |
245 | 3.52k | { |
246 | 3.52k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
247 | 3.52k | gx_device *tdev = fdev->target; |
248 | | |
249 | 3.52k | if (tdev == 0) |
250 | 0 | return_error(gs_error_Fatal); |
251 | 3.52k | return dev_proc(tdev, copy_color) |
252 | 3.52k | (tdev, data, dx, raster, id, x, y, w, h); |
253 | 3.52k | } |
254 | | |
255 | | int |
256 | | gx_forward_copy_planes(gx_device * dev, const byte * data, |
257 | | int dx, int raster, gx_bitmap_id id, |
258 | | int x, int y, int w, int h, int plane_height) |
259 | 2.45k | { |
260 | 2.45k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
261 | 2.45k | gx_device *tdev = fdev->target; |
262 | | |
263 | 2.45k | if (tdev == 0) |
264 | 0 | return_error(gs_error_Fatal); |
265 | 2.45k | return dev_proc(tdev, copy_planes) |
266 | 2.45k | (tdev, data, dx, raster, id, x, y, w, h, plane_height); |
267 | 2.45k | } |
268 | | |
269 | | int |
270 | | gx_forward_get_params(gx_device * dev, gs_param_list * plist) |
271 | 16 | { |
272 | 16 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
273 | 16 | gx_device *tdev = fdev->target; |
274 | | |
275 | 16 | return (tdev == 0 ? gx_default_get_params(dev, plist) : |
276 | 16 | dev_proc(tdev, get_params)(tdev, plist)); |
277 | 16 | } |
278 | | |
279 | | int |
280 | | gx_forward_put_params(gx_device * dev, gs_param_list * plist) |
281 | 1 | { |
282 | 1 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
283 | 1 | gx_device *tdev = fdev->target; |
284 | 1 | bool was_open; |
285 | 1 | int code; |
286 | | |
287 | 1 | if (tdev == 0) |
288 | 1 | return gx_default_put_params(dev, plist); |
289 | 0 | was_open = tdev->is_open; |
290 | 0 | code = dev_proc(tdev, put_params)(tdev, plist); |
291 | 0 | if (code == 0 && !tdev->is_open) { |
292 | 0 | code = was_open ? 1 : 0; /* target device closed */ |
293 | 0 | } |
294 | 0 | if (code >= 0) |
295 | 0 | gx_device_decache_colors(dev); |
296 | 0 | return code; |
297 | 1 | } |
298 | | |
299 | | gx_color_index |
300 | | gx_forward_map_cmyk_color(gx_device * dev, const gx_color_value cv[]) |
301 | 0 | { |
302 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
303 | 0 | gx_device *tdev = fdev->target; |
304 | |
|
305 | 0 | return (tdev == 0 ? gx_default_map_cmyk_color(dev, cv) : |
306 | 0 | dev_proc(tdev, map_cmyk_color)(tdev, cv)); |
307 | 0 | } |
308 | | |
309 | | gx_device * |
310 | | gx_forward_get_page_device(gx_device * dev) |
311 | 0 | { |
312 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
313 | 0 | gx_device *tdev = fdev->target; |
314 | 0 | gx_device *pdev; |
315 | |
|
316 | 0 | if (tdev == 0) |
317 | 0 | return gx_default_get_page_device(dev); |
318 | 0 | pdev = dev_proc(tdev, get_page_device)(tdev); |
319 | 0 | return pdev; |
320 | 0 | } |
321 | | |
322 | | int |
323 | | gx_forward_fill_path(gx_device * dev, const gs_gstate * pgs, |
324 | | gx_path * ppath, const gx_fill_params * params, |
325 | | const gx_drawing_color * pdcolor, |
326 | | const gx_clip_path * pcpath) |
327 | 2.13M | { |
328 | 2.13M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
329 | 2.13M | gx_device *tdev = fdev->target; |
330 | 2.13M | dev_proc_fill_path((*proc)) = |
331 | 2.13M | (tdev == 0 ? (tdev = dev, gx_default_fill_path) : |
332 | 2.13M | dev_proc(tdev, fill_path)); |
333 | | |
334 | 2.13M | return proc(tdev, pgs, ppath, params, pdcolor, pcpath); |
335 | 2.13M | } |
336 | | |
337 | | int |
338 | | gx_forward_stroke_path(gx_device * dev, const gs_gstate * pgs, |
339 | | gx_path * ppath, const gx_stroke_params * params, |
340 | | const gx_drawing_color * pdcolor, |
341 | | const gx_clip_path * pcpath) |
342 | 554k | { |
343 | 554k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
344 | 554k | gx_device *tdev = fdev->target; |
345 | 554k | dev_proc_stroke_path((*proc)) = |
346 | 554k | (tdev == 0 ? (tdev = dev, gx_default_stroke_path) : |
347 | 554k | dev_proc(tdev, stroke_path)); |
348 | | |
349 | 554k | return proc(tdev, pgs, ppath, params, pdcolor, pcpath); |
350 | 554k | } |
351 | | |
352 | | int |
353 | | gx_forward_fill_stroke_path(gx_device * dev, const gs_gstate * pgs, |
354 | | gx_path * ppath, |
355 | | const gx_fill_params * params_fill, |
356 | | const gx_drawing_color * pdcolor_fill, |
357 | | const gx_stroke_params * params_stroke, |
358 | | const gx_drawing_color * pdcolor_stroke, |
359 | | const gx_clip_path * pcpath) |
360 | 16.4k | { |
361 | 16.4k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
362 | 16.4k | gx_device *tdev = fdev->target; |
363 | 16.4k | dev_proc_fill_stroke_path((*proc)) = |
364 | 16.4k | (tdev == 0 ? (tdev = dev, gx_default_fill_stroke_path) : |
365 | 16.4k | dev_proc(tdev, fill_stroke_path)); |
366 | | |
367 | 16.4k | return proc(tdev, pgs, ppath, params_fill, pdcolor_fill, params_stroke, pdcolor_stroke, pcpath); |
368 | 16.4k | } |
369 | | |
370 | | int |
371 | | gx_forward_lock_pattern(gx_device * dev, gs_gstate * pgs, gs_id pattern_id, int lock) |
372 | 0 | { |
373 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
374 | 0 | gx_device *tdev = fdev->target; |
375 | 0 | dev_proc_lock_pattern((*proc)) = |
376 | 0 | (tdev == 0 ? (tdev = dev, gx_default_lock_pattern) : |
377 | 0 | dev_proc(tdev, lock_pattern)); |
378 | |
|
379 | 0 | return proc(tdev, pgs, pattern_id, lock); |
380 | |
|
381 | 0 | } |
382 | | |
383 | | int |
384 | | gx_forward_fill_mask(gx_device * dev, |
385 | | const byte * data, int dx, int raster, gx_bitmap_id id, |
386 | | int x, int y, int w, int h, |
387 | | const gx_drawing_color * pdcolor, int depth, |
388 | | gs_logical_operation_t lop, const gx_clip_path * pcpath) |
389 | 3.05k | { |
390 | 3.05k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
391 | 3.05k | gx_device *tdev = fdev->target; |
392 | 3.05k | dev_proc_fill_mask((*proc)) = |
393 | 3.05k | (tdev == 0 ? (tdev = dev, gx_default_fill_mask) : |
394 | 3.05k | dev_proc(tdev, fill_mask)); |
395 | | |
396 | 3.05k | return proc(tdev, data, dx, raster, id, x, y, w, h, pdcolor, depth, |
397 | 3.05k | lop, pcpath); |
398 | 3.05k | } |
399 | | |
400 | | int |
401 | | gx_forward_fill_trapezoid(gx_device * dev, |
402 | | const gs_fixed_edge * left, |
403 | | const gs_fixed_edge * right, |
404 | | fixed ybot, fixed ytop, bool swap_axes, |
405 | | const gx_drawing_color * pdcolor, |
406 | | gs_logical_operation_t lop) |
407 | 0 | { |
408 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
409 | 0 | gx_device *tdev = fdev->target; |
410 | 0 | dev_proc_fill_trapezoid((*proc)) = |
411 | 0 | (tdev == 0 ? (tdev = dev, gx_default_fill_trapezoid) : |
412 | 0 | dev_proc(tdev, fill_trapezoid)); |
413 | |
|
414 | 0 | return proc(tdev, left, right, ybot, ytop, swap_axes, pdcolor, lop); |
415 | 0 | } |
416 | | |
417 | | int |
418 | | gx_forward_fill_parallelogram(gx_device * dev, |
419 | | fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
420 | | const gx_drawing_color * pdcolor, gs_logical_operation_t lop) |
421 | 447k | { |
422 | 447k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
423 | 447k | gx_device *tdev = fdev->target; |
424 | 447k | dev_proc_fill_parallelogram((*proc)) = |
425 | 447k | (tdev == 0 ? (tdev = dev, gx_default_fill_parallelogram) : |
426 | 447k | dev_proc(tdev, fill_parallelogram)); |
427 | | |
428 | 447k | return proc(tdev, px, py, ax, ay, bx, by, pdcolor, lop); |
429 | 447k | } |
430 | | |
431 | | int |
432 | | gx_forward_fill_triangle(gx_device * dev, |
433 | | fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
434 | | const gx_drawing_color * pdcolor, gs_logical_operation_t lop) |
435 | 0 | { |
436 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
437 | 0 | gx_device *tdev = fdev->target; |
438 | 0 | dev_proc_fill_triangle((*proc)) = |
439 | 0 | (tdev == 0 ? (tdev = dev, gx_default_fill_triangle) : |
440 | 0 | dev_proc(tdev, fill_triangle)); |
441 | |
|
442 | 0 | return proc(tdev, px, py, ax, ay, bx, by, pdcolor, lop); |
443 | 0 | } |
444 | | |
445 | | int |
446 | | gx_forward_draw_thin_line(gx_device * dev, |
447 | | fixed fx0, fixed fy0, fixed fx1, fixed fy1, |
448 | | const gx_drawing_color * pdcolor, gs_logical_operation_t lop, |
449 | | fixed adjustx, fixed adjusty) |
450 | 0 | { |
451 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
452 | 0 | gx_device *tdev = fdev->target; |
453 | 0 | dev_proc_draw_thin_line((*proc)) = |
454 | 0 | (tdev == 0 ? (tdev = dev, gx_default_draw_thin_line) : |
455 | 0 | dev_proc(tdev, draw_thin_line)); |
456 | |
|
457 | 0 | return proc(tdev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); |
458 | 0 | } |
459 | | |
460 | | int |
461 | | gx_forward_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, |
462 | | int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, |
463 | | int px, int py) |
464 | 0 | { |
465 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
466 | 0 | gx_device *tdev = fdev->target; |
467 | 0 | dev_proc_strip_tile_rectangle((*proc)) = |
468 | 0 | (tdev == 0 ? (tdev = dev, gx_default_strip_tile_rectangle) : |
469 | 0 | dev_proc(tdev, strip_tile_rectangle)); |
470 | |
|
471 | 0 | return proc(tdev, tiles, x, y, w, h, color0, color1, px, py); |
472 | 0 | } |
473 | | |
474 | | int |
475 | | gx_forward_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, |
476 | | uint sraster, gx_bitmap_id id, |
477 | | const gx_color_index * scolors, |
478 | | const gx_strip_bitmap * textures, |
479 | | const gx_color_index * tcolors, |
480 | | int x, int y, int width, int height, |
481 | | int phase_x, int phase_y, gs_logical_operation_t lop, |
482 | | uint planar_height) |
483 | 0 | { |
484 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
485 | 0 | gx_device *tdev = fdev->target; |
486 | |
|
487 | 0 | dev_proc_strip_copy_rop2((*proc2)) = |
488 | 0 | (tdev == 0 ? (tdev = dev, gx_default_strip_copy_rop2) : |
489 | 0 | dev_proc(tdev, strip_copy_rop2)); |
490 | |
|
491 | 0 | return proc2(tdev, sdata, sourcex, sraster, id, scolors, |
492 | 0 | textures, tcolors, x, y, width, height, |
493 | 0 | phase_x, phase_y, lop, planar_height); |
494 | 0 | } |
495 | | |
496 | | int |
497 | | gx_forward_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, |
498 | | int x, int y, int w, int h, const gx_drawing_color * pdcolor0, |
499 | | const gx_drawing_color * pdcolor1, int px, int py) |
500 | 0 | { |
501 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
502 | 0 | gx_device *tdev = fdev->target; |
503 | |
|
504 | 0 | if (tdev == 0) |
505 | 0 | return gx_default_strip_tile_rect_devn(dev, tiles, x, y, w, h, pdcolor0, |
506 | 0 | pdcolor1, px, py); |
507 | 0 | else |
508 | 0 | return dev_proc(tdev, strip_tile_rect_devn)(tdev, tiles, x, y, w, h, |
509 | 0 | pdcolor0, pdcolor1, px, py); |
510 | 0 | } |
511 | | |
512 | | void |
513 | | gx_forward_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox) |
514 | 56.5k | { |
515 | 56.5k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
516 | 56.5k | gx_device *tdev = fdev->target; |
517 | | |
518 | 56.5k | if (tdev == 0) |
519 | 0 | gx_default_get_clipping_box(dev, pbox); |
520 | 56.5k | else |
521 | 56.5k | dev_proc(tdev, get_clipping_box)(tdev, pbox); |
522 | 56.5k | } |
523 | | |
524 | | int |
525 | | gx_forward_begin_typed_image(gx_device * dev, const gs_gstate * pgs, |
526 | | const gs_matrix * pmat, |
527 | | const gs_image_common_t * pim, |
528 | | const gs_int_rect * prect, |
529 | | const gx_drawing_color * pdcolor, |
530 | | const gx_clip_path * pcpath, |
531 | | gs_memory_t * memory, |
532 | | gx_image_enum_common_t ** pinfo) |
533 | 67.1k | { |
534 | 67.1k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
535 | 67.1k | gx_device *tdev = fdev->target; |
536 | 67.1k | dev_proc_begin_typed_image((*proc)) = |
537 | 67.1k | (tdev == 0 ? (tdev = dev, gx_default_begin_typed_image) : |
538 | 67.1k | dev_proc(tdev, begin_typed_image)); |
539 | | |
540 | 67.1k | return proc(tdev, pgs, pmat, pim, prect, pdcolor, pcpath, |
541 | 67.1k | memory, pinfo); |
542 | 67.1k | } |
543 | | |
544 | | int |
545 | | gx_forward_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, |
546 | | gs_get_bits_params_t * params) |
547 | 0 | { |
548 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
549 | 0 | gx_device *tdev = fdev->target; |
550 | 0 | dev_proc_get_bits_rectangle((*proc)) = |
551 | 0 | (tdev == 0 ? (tdev = dev, gx_default_get_bits_rectangle) : |
552 | 0 | dev_proc(tdev, get_bits_rectangle)); |
553 | |
|
554 | 0 | return proc(tdev, prect, params); |
555 | 0 | } |
556 | | |
557 | | int |
558 | | gx_forward_get_hardware_params(gx_device * dev, gs_param_list * plist) |
559 | 0 | { |
560 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
561 | 0 | gx_device *tdev = fdev->target; |
562 | |
|
563 | 0 | return (tdev == 0 ? gx_default_get_hardware_params(dev, plist) : |
564 | 0 | dev_proc(tdev, get_hardware_params)(tdev, plist)); |
565 | 0 | } |
566 | | |
567 | | int |
568 | | gx_forward_text_begin(gx_device * dev, gs_gstate * pgs, |
569 | | const gs_text_params_t * text, gs_font * font, |
570 | | const gx_clip_path * pcpath, |
571 | | gs_text_enum_t ** ppenum) |
572 | 4.36M | { |
573 | 4.36M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
574 | 4.36M | gx_device *tdev = fdev->target; |
575 | 4.36M | dev_proc_text_begin((*proc)) = |
576 | 4.36M | (tdev == 0 ? (tdev = dev, gx_default_text_begin) : |
577 | 4.36M | dev_proc(tdev, text_begin)); |
578 | | |
579 | 4.36M | return proc(tdev, pgs, text, font, pcpath, ppenum); |
580 | 4.36M | } |
581 | | |
582 | | /* Forwarding device color mapping procs. */ |
583 | | |
584 | | /* |
585 | | * We need to forward the color mapping to the target device. |
586 | | */ |
587 | | static void |
588 | | fwd_map_gray_cs(const gx_device * dev, frac gray, frac out[]) |
589 | 0 | { |
590 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
591 | 0 | gx_device * tdev = fdev->target; |
592 | 0 | const gx_device *cmdev; |
593 | 0 | const gx_cm_color_map_procs *cmprocs; |
594 | |
|
595 | 0 | if (tdev) { |
596 | 0 | cmprocs = dev_proc(tdev, get_color_mapping_procs)(tdev, &cmdev); |
597 | 0 | cmprocs->map_gray(cmdev, gray, out); |
598 | 0 | } |
599 | 0 | else |
600 | 0 | gray_cs_to_gray_cm(tdev, gray, out); /* if all else fails */ |
601 | 0 | } |
602 | | |
603 | | /* |
604 | | * We need to forward the color mapping to the target device. |
605 | | */ |
606 | | static void |
607 | | fwd_map_rgb_cs(const gx_device * dev, const gs_gstate *pgs, |
608 | | frac r, frac g, frac b, frac out[]) |
609 | 0 | { |
610 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
611 | 0 | gx_device * tdev = fdev->target; |
612 | 0 | const gx_device *cmdev; |
613 | 0 | const gx_cm_color_map_procs *cmprocs; |
614 | |
|
615 | 0 | if (tdev) { |
616 | 0 | cmprocs = dev_proc(tdev, get_color_mapping_procs)(tdev, &cmdev); |
617 | 0 | cmprocs->map_rgb(cmdev, pgs, r, g, b, out); |
618 | 0 | } |
619 | 0 | else |
620 | 0 | rgb_cs_to_rgb_cm(tdev, pgs, r, g, b, out); /* if all else fails */ |
621 | 0 | } |
622 | | |
623 | | /* |
624 | | * We need to forward the color mapping to the target device. |
625 | | */ |
626 | | static void |
627 | | fwd_map_cmyk_cs(const gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) |
628 | 0 | { |
629 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
630 | 0 | gx_device * tdev = fdev->target; |
631 | 0 | const gx_device *cmdev; |
632 | 0 | const gx_cm_color_map_procs *cmprocs; |
633 | |
|
634 | 0 | if (tdev) { |
635 | 0 | cmprocs = dev_proc(tdev, get_color_mapping_procs)(tdev, &cmdev); |
636 | 0 | cmprocs->map_cmyk(cmdev, c, m, y, k, out); |
637 | 0 | } |
638 | 0 | else |
639 | 0 | cmyk_cs_to_cmyk_cm(tdev, c, m, y, k, out); /* if all else fails */ |
640 | 0 | } |
641 | | |
642 | | static const gx_cm_color_map_procs FwdDevice_cm_map_procs = { |
643 | | fwd_map_gray_cs, fwd_map_rgb_cs, fwd_map_cmyk_cs |
644 | | }; |
645 | | /* |
646 | | * Instead of returning the target device's mapping procs, we need |
647 | | * to return a list of forwarding wrapper procs for the color mapping |
648 | | * procs. This is required because the target device mapping procs |
649 | | * may also need the target device pointer (instead of the forwarding |
650 | | * device pointer). |
651 | | */ |
652 | | const gx_cm_color_map_procs * |
653 | | gx_forward_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev) |
654 | 296M | { |
655 | 296M | const gx_device_forward * fdev = (const gx_device_forward *)dev; |
656 | 296M | gx_device * tdev = fdev->target; |
657 | | |
658 | 296M | if (tdev) |
659 | 296M | return dev_proc(tdev, get_color_mapping_procs)(tdev, map_dev); |
660 | | |
661 | | /* Testing in the cluster seems to indicate that we never get here, |
662 | | * but we've written the code now... */ |
663 | 0 | *map_dev = dev; |
664 | 0 | return &FwdDevice_cm_map_procs; |
665 | 296M | } |
666 | | |
667 | | int |
668 | | gx_forward_get_color_comp_index(gx_device * dev, const char * pname, |
669 | | int name_size, int component_type) |
670 | 1.20M | { |
671 | 1.20M | const gx_device_forward * fdev = (const gx_device_forward *)dev; |
672 | 1.20M | gx_device *tdev = fdev->target; |
673 | | |
674 | 1.20M | return (tdev == 0 |
675 | 1.20M | ? gx_error_get_color_comp_index(dev, pname, |
676 | 0 | name_size, component_type) |
677 | 1.20M | : dev_proc(tdev, get_color_comp_index)(tdev, pname, |
678 | 1.20M | name_size, component_type)); |
679 | 1.20M | } |
680 | | |
681 | | gx_color_index |
682 | | gx_forward_encode_color(gx_device * dev, const gx_color_value colors[]) |
683 | 2.01G | { |
684 | 2.01G | gx_device_forward * const fdev = (gx_device_forward *)dev; |
685 | 2.01G | gx_device *tdev = fdev->target; |
686 | | |
687 | 2.01G | return (tdev == 0 ? gx_error_encode_color(dev, colors) |
688 | 2.01G | : dev_proc(tdev, encode_color)(tdev, colors)); |
689 | 2.01G | } |
690 | | |
691 | | int |
692 | | gx_forward_decode_color(gx_device * dev, gx_color_index cindex, gx_color_value colors[]) |
693 | 0 | { |
694 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
695 | 0 | gx_device *tdev = fdev->target; |
696 | |
|
697 | 0 | if (tdev == 0) /* If no device - just clear the color values */ |
698 | 0 | memset(colors, 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); |
699 | 0 | else |
700 | 0 | dev_proc(tdev, decode_color)(tdev, cindex, colors); |
701 | 0 | return 0; |
702 | 0 | } |
703 | | |
704 | | int |
705 | | gx_forward_dev_spec_op(gx_device * dev, int dev_spec_op, void *data, int size) |
706 | 306M | { |
707 | 306M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
708 | 306M | gx_device *tdev = fdev->target; |
709 | | |
710 | | /* Note that clist sets fdev->target == fdev, |
711 | | so this function is unapplicable to clist. */ |
712 | 306M | if (tdev == 0) { |
713 | 0 | if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) { |
714 | 0 | return (dev_proc(dev, fill_path) == gx_default_fill_path); |
715 | 0 | } |
716 | 0 | return_error(gs_error_undefined); |
717 | 306M | } else if (dev_spec_op == gxdso_pattern_handles_clip_path) { |
718 | 0 | if (dev_proc(dev, fill_path) == gx_default_fill_path) |
719 | 0 | return 0; |
720 | 306M | } else if (dev_spec_op == gxdso_device_child) { |
721 | 3.14k | gxdso_device_child_request *d = (gxdso_device_child_request *)data; |
722 | 3.14k | if (d->target == dev) { |
723 | 3.14k | d->target = fdev->target; |
724 | 3.14k | return 1; |
725 | 3.14k | } |
726 | 306M | } else if (dev_spec_op == gxdso_device_insert_child) { |
727 | 3.14k | fdev->target = (gx_device *)data; |
728 | 3.14k | rc_increment(fdev->target); |
729 | 3.14k | rc_decrement_only(tdev, "gx_forward_device"); |
730 | 3.14k | return 0; |
731 | 3.14k | } |
732 | 306M | return dev_proc(tdev, dev_spec_op)(tdev, dev_spec_op, data, size); |
733 | 306M | } |
734 | | |
735 | | int |
736 | | gx_forward_fill_rectangle_hl_color(gx_device *dev, |
737 | | const gs_fixed_rect *rect, |
738 | | const gs_gstate *pgs, const gx_drawing_color *pdcolor, |
739 | | const gx_clip_path *pcpath) |
740 | 23.5M | { |
741 | 23.5M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
742 | 23.5M | gx_device *tdev = fdev->target; |
743 | | |
744 | | /* Note that clist sets fdev->target == fdev, |
745 | | so this function is unapplicable to clist. */ |
746 | 23.5M | if (tdev == 0) |
747 | 0 | return_error(gs_error_rangecheck); |
748 | 23.5M | else |
749 | 23.5M | return dev_proc(tdev, fill_rectangle_hl_color)(tdev, rect, |
750 | 23.5M | pgs, pdcolor, pcpath); |
751 | 23.5M | } |
752 | | |
753 | | int |
754 | | gx_forward_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, |
755 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
756 | | const gx_drawing_color *pdcolor, int depth) |
757 | 0 | { |
758 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
759 | 0 | gx_device *tdev = fdev->target; |
760 | |
|
761 | 0 | if (tdev == 0) |
762 | 0 | return_error(gs_error_rangecheck); |
763 | 0 | else |
764 | 0 | return dev_proc(tdev, copy_alpha_hl_color) |
765 | 0 | (tdev, data, data_x, raster, id, x, y, width, height, pdcolor, depth); |
766 | 0 | } |
767 | | |
768 | | int |
769 | | gx_forward_include_color_space(gx_device *dev, gs_color_space *cspace, |
770 | | const byte *res_name, int name_length) |
771 | 0 | { |
772 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
773 | 0 | gx_device *tdev = fdev->target; |
774 | | |
775 | | /* Note that clist sets fdev->target == fdev, |
776 | | so this function is unapplicable to clist. */ |
777 | 0 | if (tdev == 0) |
778 | 0 | return 0; |
779 | 0 | else |
780 | 0 | return dev_proc(tdev, include_color_space)(tdev, cspace, res_name, name_length); |
781 | 0 | } |
782 | | |
783 | | int |
784 | | gx_forward_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, |
785 | | int i, int j, int w, |
786 | | const frac31 *c, const int32_t *addx, const int32_t *mulx, int32_t divx) |
787 | 0 | { |
788 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
789 | 0 | gx_device *tdev = fdev->target; |
790 | 0 | dev_proc_fill_linear_color_scanline((*proc)) = |
791 | 0 | (tdev == 0 ? (tdev = dev, gx_default_fill_linear_color_scanline) : |
792 | 0 | dev_proc(tdev, fill_linear_color_scanline)); |
793 | 0 | return proc(tdev, fa, i, j, w, c, addx, mulx, divx); |
794 | 0 | } |
795 | | |
796 | | int |
797 | | gx_forward_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, |
798 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
799 | | const gs_fixed_point *p2, const gs_fixed_point *p3, |
800 | | const frac31 *c0, const frac31 *c1, |
801 | | const frac31 *c2, const frac31 *c3) |
802 | 39 | { |
803 | 39 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
804 | 39 | gx_device *tdev = fdev->target; |
805 | 39 | dev_proc_fill_linear_color_trapezoid((*proc)) = |
806 | 39 | (tdev == 0 ? (tdev = dev, gx_default_fill_linear_color_trapezoid) : |
807 | 39 | dev_proc(tdev, fill_linear_color_trapezoid)); |
808 | 39 | return proc(tdev, fa, p0, p1, p2, p3, c0, c1, c2, c3); |
809 | 39 | } |
810 | | |
811 | | int |
812 | | gx_forward_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, |
813 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
814 | | const gs_fixed_point *p2, |
815 | | const frac31 *c0, const frac31 *c1, const frac31 *c2) |
816 | 14 | { |
817 | 14 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
818 | 14 | gx_device *tdev = fdev->target; |
819 | 14 | dev_proc_fill_linear_color_triangle((*proc)) = |
820 | 14 | (tdev == 0 ? (tdev = dev, gx_default_fill_linear_color_triangle) : |
821 | 14 | dev_proc(tdev, fill_linear_color_triangle)); |
822 | 14 | return proc(tdev, fa, p0, p1, p2, c0, c1, c2); |
823 | 14 | } |
824 | | |
825 | | int |
826 | | gx_forward_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs, const gs_color_space *pcs) |
827 | 20.5k | { |
828 | 20.5k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
829 | 20.5k | gx_device *tdev = fdev->target; |
830 | 20.5k | int code = 0; |
831 | | |
832 | 20.5k | if (tdev != NULL) |
833 | 20.5k | code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs); |
834 | 20.5k | return code; |
835 | 20.5k | } |
836 | | |
837 | | gs_devn_params * |
838 | | gx_forward_ret_devn_params(gx_device *dev) |
839 | 145k | { |
840 | 145k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
841 | 145k | gx_device *tdev = fdev->target; |
842 | | |
843 | 145k | if (tdev != NULL) |
844 | 145k | return dev_proc(tdev, ret_devn_params)(tdev); |
845 | 0 | return NULL; |
846 | 145k | } |
847 | | |
848 | | int |
849 | | gx_forward_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) |
850 | 0 | { |
851 | 0 | gx_device_forward * const fdev = (gx_device_forward *)dev; |
852 | 0 | gx_device *tdev = fdev->target; |
853 | 0 | dev_proc_fillpage((*proc)) = |
854 | 0 | (tdev == 0 ? (tdev = dev, gx_default_fillpage) : |
855 | 0 | dev_proc(tdev, fillpage)); |
856 | 0 | return proc(tdev, pgs, pdevc); |
857 | 0 | } |
858 | | |
859 | | int |
860 | | gx_forward_composite(gx_device * dev, gx_device ** pcdev, |
861 | | const gs_composite_t * pcte, |
862 | | gs_gstate * pgs, gs_memory_t * memory, |
863 | | gx_device *cdev) |
864 | 80.3k | { |
865 | 80.3k | gx_device_forward * const fdev = (gx_device_forward *)dev; |
866 | 80.3k | gx_device *tdev = fdev->target; |
867 | 80.3k | int code; |
868 | | |
869 | 80.3k | if (tdev == 0) |
870 | 0 | return gx_no_composite(dev, pcdev, pcte, pgs, memory, cdev); |
871 | | /* else do the compositor action */ |
872 | 80.3k | code = dev_proc(tdev, composite)(tdev, pcdev, pcte, pgs, memory, cdev); |
873 | | /* the compositor may have changed color_info. Pick up the new value */ |
874 | 80.3k | dev->color_info = tdev->color_info; |
875 | 80.3k | if (code == 1) { |
876 | | /* If a new compositor was made that wrapped tdev, then that |
877 | | * compositor should be our target now. */ |
878 | 20 | gx_device_set_target((gx_device_forward *)dev, *pcdev); |
879 | 20 | code = 0; /* We have not made a new compositor that wrapped dev. */ |
880 | 20 | } |
881 | 80.3k | return code; |
882 | 80.3k | } |
883 | | |
884 | | int |
885 | | gx_forward_get_profile(const gx_device *dev, cmm_dev_profile_t **profile) |
886 | 462M | { |
887 | 462M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
888 | 462M | const gx_device *tdev = fdev->target; |
889 | | |
890 | 462M | if (tdev == NULL) |
891 | 0 | return gx_default_get_profile(dev, profile); |
892 | 462M | return dev_proc(tdev, get_profile)(tdev, profile); |
893 | 462M | } |
894 | | |
895 | | void |
896 | | gx_forward_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t graphics_type_tag) |
897 | 1.84M | { |
898 | 1.84M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
899 | 1.84M | gx_device *tdev = fdev->target; |
900 | | |
901 | 1.84M | if (tdev != 0) |
902 | 1.84M | dev_proc(tdev, set_graphics_type_tag)(tdev, graphics_type_tag); |
903 | | /* Keep copy in this device current, and preserve GS_DEVICE_ENCODES_TAGS */ |
904 | 1.84M | dev->graphics_type_tag = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) | graphics_type_tag; |
905 | 1.84M | } |
906 | | |
907 | | int |
908 | | gx_forward_put_image(gx_device *pdev, gx_device *mdev, const byte **buffers, int num_chan, int xstart, |
909 | | int ystart, int width, int height, int row_stride, |
910 | | int alpha_plane_index, int tag_plane_index) |
911 | 46.4k | { |
912 | 46.4k | gx_device_forward * const fdev = (gx_device_forward *)pdev; |
913 | 46.4k | gx_device *tdev = fdev->target; |
914 | | |
915 | 46.4k | if (tdev != 0) |
916 | 46.4k | return dev_proc(tdev, put_image)(tdev, mdev, buffers, num_chan, xstart, ystart, width, height, row_stride, alpha_plane_index, tag_plane_index); |
917 | 0 | else |
918 | 0 | return gx_default_put_image(tdev, mdev, buffers, num_chan, xstart, ystart, width, height, row_stride, alpha_plane_index, tag_plane_index); |
919 | 46.4k | } |
920 | | |
921 | | int |
922 | | gx_forward_transform_pixel_region(gx_device *pdev, transform_pixel_region_reason reason, transform_pixel_region_data *data) |
923 | 0 | { |
924 | 0 | gx_device_forward * const fdev = (gx_device_forward *)pdev; |
925 | 0 | gx_device *tdev = fdev->target; |
926 | |
|
927 | 0 | if (tdev != 0) |
928 | 0 | return dev_proc(tdev, transform_pixel_region)(tdev, reason, data); |
929 | 0 | else |
930 | 0 | return gx_default_transform_pixel_region(pdev, reason, data); |
931 | 0 | } |
932 | | |
933 | | /* ---------------- The null device(s) ---------_plane_index------- */ |
934 | | |
935 | | static dev_proc_get_initial_matrix(gx_forward_upright_get_initial_matrix); |
936 | | static dev_proc_fill_rectangle(null_fill_rectangle); |
937 | | static dev_proc_copy_mono(null_copy_mono); |
938 | | static dev_proc_copy_color(null_copy_color); |
939 | | static dev_proc_put_params(null_put_params); |
940 | | static dev_proc_copy_alpha(null_copy_alpha); |
941 | | static dev_proc_fill_path(null_fill_path); |
942 | | static dev_proc_stroke_path(null_stroke_path); |
943 | | static dev_proc_fill_trapezoid(null_fill_trapezoid); |
944 | | static dev_proc_fill_parallelogram(null_fill_parallelogram); |
945 | | static dev_proc_fill_triangle(null_fill_triangle); |
946 | | static dev_proc_draw_thin_line(null_draw_thin_line); |
947 | | static dev_proc_decode_color(null_decode_color); |
948 | | /* We would like to have null implementations of begin/data/end image, */ |
949 | | /* but we can't do this, because image_data must keep track of the */ |
950 | | /* Y position so it can return 1 when done. */ |
951 | | static dev_proc_strip_copy_rop2(null_strip_copy_rop2); |
952 | | static dev_proc_strip_tile_rect_devn(null_strip_tile_rect_devn); |
953 | | static dev_proc_fill_rectangle_hl_color(null_fill_rectangle_hl_color); |
954 | | static dev_proc_dev_spec_op(null_spec_op); |
955 | | |
956 | | static void |
957 | | null_initialize_device_procs(gx_device *dev) |
958 | 17.6M | { |
959 | 17.6M | set_dev_proc(dev, get_initial_matrix, gx_forward_upright_get_initial_matrix); |
960 | 17.6M | set_dev_proc(dev, get_page_device, gx_default_get_page_device); |
961 | 17.6M | set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); |
962 | 17.6M | set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); |
963 | 17.6M | set_dev_proc(dev, fill_rectangle, null_fill_rectangle); |
964 | 17.6M | set_dev_proc(dev, copy_mono, null_copy_mono); |
965 | 17.6M | set_dev_proc(dev, copy_color, null_copy_color); |
966 | 17.6M | set_dev_proc(dev, get_params, gx_forward_get_params); |
967 | 17.6M | set_dev_proc(dev, put_params, null_put_params); |
968 | 17.6M | set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); |
969 | 17.6M | set_dev_proc(dev, copy_alpha, null_copy_alpha); |
970 | 17.6M | set_dev_proc(dev, fill_path, null_fill_path); |
971 | 17.6M | set_dev_proc(dev, stroke_path, null_stroke_path); |
972 | 17.6M | set_dev_proc(dev, fill_trapezoid, null_fill_trapezoid); |
973 | 17.6M | set_dev_proc(dev, fill_parallelogram, null_fill_parallelogram); |
974 | 17.6M | set_dev_proc(dev, fill_triangle, null_fill_triangle); |
975 | 17.6M | set_dev_proc(dev, draw_thin_line, null_draw_thin_line); |
976 | 17.6M | set_dev_proc(dev, composite, gx_non_imaging_composite); |
977 | 17.6M | set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); |
978 | 17.6M | set_dev_proc(dev, get_color_mapping_procs, gx_default_DevGray_get_color_mapping_procs); |
979 | 17.6M | set_dev_proc(dev, get_color_comp_index, gx_default_DevGray_get_color_comp_index); |
980 | 17.6M | set_dev_proc(dev, encode_color, gx_default_gray_fast_encode); |
981 | 17.6M | set_dev_proc(dev, decode_color, null_decode_color); |
982 | 17.6M | set_dev_proc(dev, fill_rectangle_hl_color, null_fill_rectangle_hl_color); |
983 | 17.6M | set_dev_proc(dev, dev_spec_op, null_spec_op); |
984 | 17.6M | set_dev_proc(dev, strip_copy_rop2, null_strip_copy_rop2); |
985 | 17.6M | set_dev_proc(dev, strip_tile_rect_devn, null_strip_tile_rect_devn); |
986 | 17.6M | } |
987 | | |
988 | | static void |
989 | | nullpage_initialize_device_procs(gx_device *dev) |
990 | 0 | { |
991 | 0 | null_initialize_device_procs(dev); |
992 | |
|
993 | 0 | set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); |
994 | 0 | set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); |
995 | 0 | } |
996 | | |
997 | | #define NULLD_X_RES 72 |
998 | | #define NULLD_Y_RES 72 |
999 | | |
1000 | | const gx_device_null gs_null_device = { |
1001 | | std_device_std_body_type_open(gx_device_null, |
1002 | | null_initialize_device_procs, |
1003 | | "null", &st_device_null, |
1004 | | 0, 0, NULLD_X_RES, NULLD_Y_RES) |
1005 | | }; |
1006 | | |
1007 | | const gx_device_null gs_nullpage_device = { |
1008 | | std_device_std_body_type_open(gx_device_null, |
1009 | | nullpage_initialize_device_procs, |
1010 | | "nullpage", &st_device_null, |
1011 | | (int)((float)(DEFAULT_WIDTH_10THS * NULLD_X_RES) / 10), |
1012 | | (int)((float)(DEFAULT_HEIGHT_10THS * NULLD_Y_RES) / 10), |
1013 | | NULLD_X_RES, NULLD_Y_RES) |
1014 | | }; |
1015 | | |
1016 | | static void |
1017 | | gx_forward_upright_get_initial_matrix(gx_device * dev, gs_matrix * pmat) |
1018 | 1.54M | { |
1019 | 1.54M | gx_device_forward * const fdev = (gx_device_forward *)dev; |
1020 | 1.54M | gx_device *tdev = fdev->target; |
1021 | | |
1022 | 1.54M | if (tdev == 0) |
1023 | 1.54M | gx_upright_get_initial_matrix(dev, pmat); |
1024 | 0 | else |
1025 | 0 | dev_proc(tdev, get_initial_matrix)(tdev, pmat); |
1026 | 1.54M | } |
1027 | | |
1028 | | static int |
1029 | | null_decode_color(gx_device * dev, gx_color_index cindex, gx_color_value colors[]) |
1030 | 0 | { |
1031 | 0 | colors[0] = (cindex & 1) ? gx_max_color_value : 0; |
1032 | 0 | return 0; |
1033 | 0 | } |
1034 | | |
1035 | | static int |
1036 | | null_fill_rectangle(gx_device * dev, int x, int y, int w, int h, |
1037 | | gx_color_index color) |
1038 | 0 | { |
1039 | 0 | return 0; |
1040 | 0 | } |
1041 | | static int |
1042 | | null_copy_mono(gx_device * dev, const byte * data, int dx, int raster, |
1043 | | gx_bitmap_id id, int x, int y, int w, int h, |
1044 | | gx_color_index zero, gx_color_index one) |
1045 | 0 | { |
1046 | 0 | return 0; |
1047 | 0 | } |
1048 | | static int |
1049 | | null_copy_color(gx_device * dev, const byte * data, |
1050 | | int data_x, int raster, gx_bitmap_id id, |
1051 | | int x, int y, int width, int height) |
1052 | 0 | { |
1053 | 0 | return 0; |
1054 | 0 | } |
1055 | | static int |
1056 | | null_put_params(gx_device * dev, gs_param_list * plist) |
1057 | 1 | { |
1058 | 1 | int code; |
1059 | 1 | cmm_dev_profile_t *iccs = dev->icc_struct; |
1060 | | |
1061 | | /* |
1062 | | * If this is not a page device, we must defeat attempts to reset |
1063 | | * the size; otherwise this is equivalent to gx_forward_put_params. |
1064 | | * Equally, we don't want it to unexpectectly error out on certain |
1065 | | * ICC parameters - so defeat those, too. |
1066 | | */ |
1067 | 1 | dev->icc_struct = NULL; |
1068 | 1 | code = gx_forward_put_params(dev, plist); |
1069 | 1 | rc_decrement(dev->icc_struct, "null_put_params"); |
1070 | 1 | dev->icc_struct = iccs; |
1071 | | |
1072 | 1 | if (code < 0 || dev_proc(dev, get_page_device)(dev) == dev) |
1073 | 0 | return code; |
1074 | 1 | dev->width = dev->height = 0; |
1075 | 1 | return code; |
1076 | 1 | } |
1077 | | static int |
1078 | | null_copy_alpha(gx_device * dev, const byte * data, int data_x, int raster, |
1079 | | gx_bitmap_id id, int x, int y, int width, int height, |
1080 | | gx_color_index color, int depth) |
1081 | 0 | { |
1082 | 0 | return 0; |
1083 | 0 | } |
1084 | | static int |
1085 | | null_fill_path(gx_device * dev, const gs_gstate * pgs, |
1086 | | gx_path * ppath, const gx_fill_params * params, |
1087 | | const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) |
1088 | 0 | { |
1089 | 0 | return 0; |
1090 | 0 | } |
1091 | | static int |
1092 | | null_stroke_path(gx_device * dev, const gs_gstate * pgs, |
1093 | | gx_path * ppath, const gx_stroke_params * params, |
1094 | | const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) |
1095 | 0 | { |
1096 | 0 | return 0; |
1097 | 0 | } |
1098 | | static int |
1099 | | null_fill_trapezoid(gx_device * dev, |
1100 | | const gs_fixed_edge * left, const gs_fixed_edge * right, |
1101 | | fixed ybot, fixed ytop, bool swap_axes, |
1102 | | const gx_drawing_color * pdcolor, |
1103 | | gs_logical_operation_t lop) |
1104 | 0 | { |
1105 | 0 | return 0; |
1106 | 0 | } |
1107 | | static int |
1108 | | null_fill_parallelogram(gx_device * dev, fixed px, fixed py, |
1109 | | fixed ax, fixed ay, fixed bx, fixed by, |
1110 | | const gx_drawing_color * pdcolor, |
1111 | | gs_logical_operation_t lop) |
1112 | 0 | { |
1113 | 0 | return 0; |
1114 | 0 | } |
1115 | | static int |
1116 | | null_fill_triangle(gx_device * dev, |
1117 | | fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
1118 | | const gx_drawing_color * pdcolor, |
1119 | | gs_logical_operation_t lop) |
1120 | 0 | { |
1121 | 0 | return 0; |
1122 | 0 | } |
1123 | | static int |
1124 | | null_draw_thin_line(gx_device * dev, |
1125 | | fixed fx0, fixed fy0, fixed fx1, fixed fy1, |
1126 | | const gx_drawing_color * pdcolor, |
1127 | | gs_logical_operation_t lop, |
1128 | | fixed adjustx, fixed adjusty) |
1129 | 0 | { |
1130 | 0 | return 0; |
1131 | 0 | } |
1132 | | static int |
1133 | | null_strip_copy_rop2(gx_device * dev, const byte * sdata, int sourcex, |
1134 | | uint sraster, gx_bitmap_id id, |
1135 | | const gx_color_index * scolors, |
1136 | | const gx_strip_bitmap * textures, |
1137 | | const gx_color_index * tcolors, |
1138 | | int x, int y, int width, int height, |
1139 | | int phase_x, int phase_y, gs_logical_operation_t lop, |
1140 | | uint plane_height) |
1141 | 0 | { |
1142 | 0 | return 0; |
1143 | 0 | } |
1144 | | |
1145 | | static int |
1146 | | null_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles, |
1147 | | int x, int y, int w, int h, const gx_drawing_color * pdcolor0, |
1148 | | const gx_drawing_color * pdcolor1, int px, int py) |
1149 | 0 | { |
1150 | 0 | return 0; |
1151 | 0 | } |
1152 | | |
1153 | | /* We use this to erase a pattern background, if pdfwrite has pushed |
1154 | | * the NULL device to dispense with text (because its a strinwidth) |
1155 | | * we don't want to throw an error when erasing the pattern which |
1156 | | * fills the text, because pdfwrite manages the pattern itself and |
1157 | | * we don't need to erase hte background. More generally, since the |
1158 | | * null device is a bit bucket, it shouldn't really throw errors |
1159 | | * when asked to render anything at all. |
1160 | | */ |
1161 | | static int null_fill_rectangle_hl_color(gx_device *pdev, |
1162 | | const gs_fixed_rect *rect, |
1163 | | const gs_gstate *pgs, const gx_drawing_color *pdcolor, |
1164 | | const gx_clip_path *pcpath) |
1165 | 45 | { |
1166 | 45 | return 0; |
1167 | 45 | } |
1168 | | |
1169 | | static int |
1170 | | null_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) |
1171 | 1.63M | { |
1172 | | /* Defeat the ICC profile components check, which we want to do since |
1173 | | we also short-circuit ICC device parameters - see null_put_params. |
1174 | | */ |
1175 | 1.63M | if (dev_spec_op == gxdso_skip_icc_component_validation) |
1176 | 94.6k | return 1; |
1177 | 1.53M | if (dev_spec_op == gxdso_is_null_device) |
1178 | 0 | return 1; |
1179 | 1.53M | return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); |
1180 | 1.53M | } |
1181 | | |
1182 | | void gx_forward_device_initialize_procs(gx_device *dev) |
1183 | 0 | { |
1184 | 0 | fill_dev_proc(dev, close_device, gx_forward_close_device); |
1185 | 0 | fill_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); |
1186 | 0 | fill_dev_proc(dev, sync_output, gx_forward_sync_output); |
1187 | 0 | fill_dev_proc(dev, output_page, gx_forward_output_page); |
1188 | 0 | fill_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); |
1189 | 0 | fill_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); |
1190 | 0 | fill_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle); |
1191 | 0 | fill_dev_proc(dev, copy_mono, gx_forward_copy_mono); |
1192 | 0 | fill_dev_proc(dev, copy_color, gx_forward_copy_color); |
1193 | 0 | fill_dev_proc(dev, get_params, gx_forward_get_params); |
1194 | 0 | fill_dev_proc(dev, put_params, gx_forward_put_params); |
1195 | 0 | fill_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); |
1196 | 0 | fill_dev_proc(dev, get_page_device, gx_forward_get_page_device); |
1197 | 0 | fill_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); |
1198 | 0 | fill_dev_proc(dev, copy_alpha, gx_forward_copy_alpha); |
1199 | 0 | fill_dev_proc(dev, fill_path, gx_forward_fill_path); |
1200 | 0 | fill_dev_proc(dev, stroke_path, gx_forward_stroke_path); |
1201 | 0 | fill_dev_proc(dev, fill_mask, gx_forward_fill_mask); |
1202 | 0 | fill_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid); |
1203 | 0 | fill_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram); |
1204 | 0 | fill_dev_proc(dev, fill_triangle, gx_forward_fill_triangle); |
1205 | 0 | fill_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line); |
1206 | 0 | fill_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle); |
1207 | 0 | fill_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); |
1208 | 0 | fill_dev_proc(dev, begin_typed_image, gx_forward_begin_typed_image); |
1209 | 0 | fill_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); |
1210 | | /* There is no forward_composite (see Drivers.htm). */ |
1211 | 0 | fill_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); |
1212 | 0 | fill_dev_proc(dev, text_begin, gx_forward_text_begin); |
1213 | 0 | fill_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs); |
1214 | 0 | fill_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index); |
1215 | 0 | fill_dev_proc(dev, encode_color, gx_forward_encode_color); |
1216 | 0 | fill_dev_proc(dev, decode_color, gx_forward_decode_color); |
1217 | 0 | fill_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op); |
1218 | 0 | fill_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color); |
1219 | 0 | fill_dev_proc(dev, include_color_space, gx_forward_include_color_space); |
1220 | 0 | fill_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline); |
1221 | 0 | fill_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid); |
1222 | 0 | fill_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle); |
1223 | 0 | fill_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors); |
1224 | 0 | fill_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params); |
1225 | 0 | fill_dev_proc(dev, fillpage, gx_forward_fillpage); |
1226 | 0 | fill_dev_proc(dev, put_image, gx_forward_put_image); |
1227 | 0 | fill_dev_proc(dev, copy_planes, gx_forward_copy_planes); |
1228 | 0 | fill_dev_proc(dev, composite, gx_forward_composite); |
1229 | 0 | fill_dev_proc(dev, get_profile, gx_forward_get_profile); |
1230 | 0 | fill_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); |
1231 | 0 | fill_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2); |
1232 | 0 | fill_dev_proc(dev, strip_tile_rect_devn, gx_forward_strip_tile_rect_devn); |
1233 | 0 | fill_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color); |
1234 | 0 | fill_dev_proc(dev, transform_pixel_region, gx_forward_transform_pixel_region); |
1235 | 0 | fill_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path); |
1236 | 0 | } |
1237 | | |
1238 | | #ifdef DEBUG |
1239 | | static void do_device_dump(gx_device *dev, int n) |
1240 | | { |
1241 | | int i, ret; |
1242 | | gxdso_device_child_request data; |
1243 | | |
1244 | | /* Dump the details of device dev */ |
1245 | | for (i = 0; i < n; i++) |
1246 | | dmlprintf(dev->memory, " "); |
1247 | | if (dev == NULL) { |
1248 | | dmlprintf(dev->memory, "NULL\n"); |
1249 | | return; |
1250 | | } |
1251 | | dmlprintf3(dev->memory, PRI_INTPTR"(%ld) = '%s'\n", (intptr_t)dev, dev->rc.ref_count, dev->dname); |
1252 | | |
1253 | | data.n = 0; |
1254 | | do { |
1255 | | data.target = dev; |
1256 | | ret = dev_proc(dev, dev_spec_op)(dev, gxdso_device_child, &data, sizeof(data)); |
1257 | | if (ret > 0) |
1258 | | do_device_dump(data.target, n+1); |
1259 | | } while ((ret > 0) && (data.n != 0)); |
1260 | | } |
1261 | | |
1262 | | void gx_device_dump(gx_device *dev, const char *text) |
1263 | | { |
1264 | | dmlprintf1(dev->memory, "%s", text); |
1265 | | do_device_dump(dev, 0); |
1266 | | } |
1267 | | #endif |