/src/ghostpdl/base/gdevsclass.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2024 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 | | /* Common code for subclassing devices */ |
17 | | #include "math_.h" |
18 | | #include "memory_.h" |
19 | | #include "gx.h" |
20 | | #include "gserrors.h" |
21 | | #include "gsparam.h" |
22 | | #include "gxdevice.h" |
23 | | #include "gsdevice.h" /* requires gsmatrix.h */ |
24 | | #include "gxdcolor.h" /* for gx_device_black/white */ |
25 | | #include "gxiparam.h" /* for image source size */ |
26 | | #include "gxgstate.h" |
27 | | #include "gxpaint.h" |
28 | | #include "gxpath.h" |
29 | | #include "gxcpath.h" |
30 | | #include "gxcmap.h" /* color mapping procs */ |
31 | | #include "gsstype.h" |
32 | | #include "gdevprn.h" |
33 | | #include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ |
34 | | #include "gdevsclass.h" |
35 | | #include "gxdevsop.h" |
36 | | |
37 | | /* |
38 | | * It would be nice if we could rewrite the clist handling to use this kind of device class chain |
39 | | * instead of the nasty hackery it currently utilises (stores the device procs for the existing |
40 | | * device in 'orig_procs' which is in the device structure) and overwrites the procs with its |
41 | | * own ones. The bbox forwarding device could also be rewritten this way and would probably then |
42 | | * be usable as a real forwarding device (last time I tried to do this for eps2write I was unable |
43 | | * to solve the problems with text enumerators). |
44 | | */ |
45 | | |
46 | | /* At first sight we should never have a method in a device structure which is NULL |
47 | | * because gx_device_fill_in_procs() should replace all the NULLs with default routines. |
48 | | * However, obselete routines, and a number of newer routines (especially those involving |
49 | | * transparency) don't get filled in. Its not obvious to me if this is deliberate or not, |
50 | | * but we'll be careful and check the subclassed device's method before trying to execute |
51 | | * it. Same for all the methods. NB the fill_rectangle method is deliberately not filled in |
52 | | * because that gets set up by gdev_prn_allocate_memory(). Isn't it great the way we do our |
53 | | * initialisation in lots of places? |
54 | | */ |
55 | | |
56 | | /* TODO make gx_device_fill_in_procs fill in *all* the procs, currently it doesn't. |
57 | | * this will mean declaring gx_default_ methods for the transparency methods, possibly |
58 | | * some others. Like a number of other default methods, these can simply return an error |
59 | | * which hopefuly will avoid us having to check for NULL device methods. |
60 | | * We also agreed to set the fill_rectangle method to a default as well (currently it explicitly |
61 | | * does not do this) and have gdev_prn_alloc_buffer check to see if the method is the default |
62 | | * before overwriting it, rather than the current check for NULL. |
63 | | */ |
64 | | |
65 | | /* More observations; method naems, we have text_begin, but begin_typed_image. |
66 | | * The enumerator initialiser for images gx_image_enum_common_init doesn't initialise |
67 | | * the 'memory' member variable. The text enumerator initialiser gs_text_enum_init does. |
68 | | * The default text enum init routine increments the reference count of the device, but the image enumerator |
69 | | * doesn't. |
70 | | */ |
71 | | |
72 | | /* We have a device method for 'get_profile' but we don't have one for 'set_profile' which causes some |
73 | | * problems, the 'set' simply sets the profile in the top device. This is modified in gsicc_set_device_profile |
74 | | * for now but really should have a method to itself. |
75 | | * |
76 | | * And in a delightful asymmetry, we have a set_graphics_type_tag, but no get_graphics_type_tag. Instead |
77 | | * (shudder) the code pulls the currently encoded colour and tag *directly* from the current device. |
78 | | * This means we have to copy the ENCODE_TAGS from the device we are subclassing, into the device which |
79 | | * is newly created at installation time. We also have to have our default set_graphics_type_tag method |
80 | | * update its graphics_type_tag, even though this device has no interest in it, just in case we happen |
81 | | * to be the top device in the chain...... |
82 | | */ |
83 | | |
84 | | /* |
85 | | * gsdparam.c line 272 checks for method being NULL, this is bad, we should check for a return error |
86 | | * or default method and do initialisation based on that. |
87 | | */ |
88 | | |
89 | | |
90 | | /* For printing devices the 'open' routine in gdevprn calls gdevprn_allocate_memory |
91 | | * which is responsible for creating the page buffer. This *also* fills in some of |
92 | | * the device procs, in particular fill_rectangle() so its vitally important that |
93 | | * we pass this on. |
94 | | */ |
95 | | int default_subclass_open_device(gx_device *dev) |
96 | 0 | { |
97 | 0 | int code = 0; |
98 | | |
99 | | /* observed with Bug 699794, don't set is_open = true if the open_device failed */ |
100 | | /* and make sure to propagate the return code from the child device to caller. */ |
101 | | /* Only open the child if it was closed and if child open is OK, return 1. */ |
102 | | /* (see gs_opendevice) */ |
103 | 0 | if (dev->child && dev->child->is_open == 0) { |
104 | 0 | code = dev_proc(dev->child, open_device)(dev->child); |
105 | 0 | if (code >= 0) { |
106 | 0 | dev->child->is_open = true; |
107 | 0 | code = 1; /* device had been closed, but now is open */ |
108 | 0 | } |
109 | 0 | gx_update_from_subclass(dev); /* this is probably safe to do even if the open failed */ |
110 | 0 | } |
111 | 0 | return code; |
112 | 0 | } |
113 | | |
114 | | void default_subclass_get_initial_matrix(gx_device *dev, gs_matrix *pmat) |
115 | 1.40M | { |
116 | 1.40M | if (dev->child) |
117 | 1.40M | dev_proc(dev->child, get_initial_matrix)(dev->child, pmat); |
118 | 0 | else |
119 | 0 | gx_default_get_initial_matrix(dev, pmat); |
120 | 1.40M | return; |
121 | 1.40M | } |
122 | | |
123 | | int default_subclass_sync_output(gx_device *dev) |
124 | 257k | { |
125 | 257k | if (dev->child) |
126 | 257k | return dev_proc(dev->child, sync_output)(dev->child); |
127 | | /* else */ |
128 | 0 | return gx_default_sync_output(dev); |
129 | 257k | } |
130 | | |
131 | | int default_subclass_output_page(gx_device *dev, int num_copies, int flush) |
132 | 26.2k | { |
133 | 26.2k | int code = 0; |
134 | | |
135 | 26.2k | if (dev->child) { |
136 | 26.2k | code = dev_proc(dev->child, output_page)(dev->child, num_copies, flush); |
137 | 26.2k | dev->PageCount = dev->child->PageCount; |
138 | 26.2k | return code; |
139 | 26.2k | } |
140 | 0 | dev->PageCount += num_copies; /* a minor lie */ |
141 | 0 | return 0; |
142 | 26.2k | } |
143 | | |
144 | | int default_subclass_close_device(gx_device *dev) |
145 | 31.6k | { |
146 | 31.6k | int code; |
147 | | |
148 | 31.6k | if (dev->child) { |
149 | 31.6k | code = dev_proc(dev->child, close_device)(dev->child); |
150 | 31.6k | dev->is_open = dev->child->is_open = false; |
151 | 31.6k | return code; |
152 | 31.6k | } |
153 | 0 | dev->is_open = false; |
154 | 0 | return 0; |
155 | 31.6k | } |
156 | | |
157 | | gx_color_index default_subclass_map_rgb_color(gx_device *dev, const gx_color_value cv[]) |
158 | 0 | { |
159 | 0 | if (dev->child) |
160 | 0 | return dev_proc(dev->child, map_rgb_color)(dev->child, cv); |
161 | 0 | else |
162 | 0 | gx_error_encode_color(dev, cv); |
163 | 0 | return 0; |
164 | 0 | } |
165 | | |
166 | | int default_subclass_map_color_rgb(gx_device *dev, gx_color_index color, gx_color_value rgb[3]) |
167 | 0 | { |
168 | 0 | if (dev->child) |
169 | 0 | return dev_proc(dev->child, map_color_rgb)(dev->child, color, rgb); |
170 | | /* else */ |
171 | 0 | return gx_default_map_color_rgb(dev, color, rgb); |
172 | 0 | } |
173 | | |
174 | | int default_subclass_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) |
175 | 1.22M | { |
176 | 1.22M | if (dev->child) |
177 | 1.22M | return dev_proc(dev->child, fill_rectangle)(dev->child, x, y, width, height, color); |
178 | 0 | return 0; |
179 | 1.22M | } |
180 | | |
181 | | int default_subclass_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
182 | | int x, int y, int width, int height, |
183 | | gx_color_index color0, gx_color_index color1) |
184 | 0 | { |
185 | 0 | if (dev->child) |
186 | 0 | return dev_proc(dev->child, copy_mono)(dev->child, data, data_x, raster, id, x, y, width, height, color0, color1); |
187 | 0 | return 0; |
188 | 0 | } |
189 | | |
190 | | int default_subclass_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id,\ |
191 | | int x, int y, int width, int height) |
192 | 0 | { |
193 | 0 | if (dev->child) |
194 | 0 | return dev_proc(dev->child, copy_color)(dev->child, data, data_x, raster, id, x, y, width, height); |
195 | 0 | return 0; |
196 | 0 | } |
197 | | |
198 | | int default_subclass_get_params(gx_device *dev, gs_param_list *plist) |
199 | 458k | { |
200 | 458k | if (dev->child) |
201 | 458k | return dev_proc(dev->child, get_params)(dev->child, plist); |
202 | | /* else */ |
203 | 0 | return gx_default_get_params(dev, plist); |
204 | 458k | } |
205 | | |
206 | | int default_subclass_put_params(gx_device *dev, gs_param_list *plist) |
207 | 178k | { |
208 | 178k | int code; |
209 | | |
210 | 178k | if (dev->child) { |
211 | 178k | code = dev_proc(dev->child, put_params)(dev->child, plist); |
212 | | /* The child device might have closed itself (yes seriously, this can happen!) */ |
213 | 178k | dev->is_open = dev->child->is_open; |
214 | 178k | gx_update_from_subclass(dev); |
215 | 178k | return code; |
216 | 178k | } |
217 | | /* else */ |
218 | 0 | return gx_default_put_params(dev, plist); |
219 | 178k | } |
220 | | |
221 | | gx_color_index default_subclass_map_cmyk_color(gx_device *dev, const gx_color_value cv[]) |
222 | 0 | { |
223 | 0 | if (dev->child) |
224 | 0 | return dev_proc(dev->child, map_cmyk_color)(dev->child, cv); |
225 | | /* else */ |
226 | 0 | return gx_default_map_cmyk_color(dev, cv); |
227 | 0 | } |
228 | | |
229 | | gx_device *default_subclass_get_page_device(gx_device *dev) |
230 | 7.50M | { |
231 | 7.50M | if (dev->child) |
232 | 7.50M | return dev_proc(dev->child, get_page_device)(dev->child); |
233 | | /* else */ |
234 | 0 | return gx_default_get_page_device(dev); |
235 | 7.50M | } |
236 | | |
237 | | int default_subclass_get_alpha_bits(gx_device *dev, graphics_object_type type) |
238 | 19.3M | { |
239 | 19.3M | if (dev->child) |
240 | 19.3M | return dev_proc(dev->child, get_alpha_bits)(dev->child, type); |
241 | 0 | return 0; |
242 | 19.3M | } |
243 | | |
244 | | int default_subclass_copy_alpha(gx_device *dev, const byte *data, int data_x, |
245 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
246 | | gx_color_index color, int depth) |
247 | 0 | { |
248 | 0 | if (dev->child) |
249 | 0 | return dev_proc(dev->child, copy_alpha)(dev->child, data, data_x, raster, id, x, y, width, height, color, depth); |
250 | 0 | return 0; |
251 | 0 | } |
252 | | |
253 | | int default_subclass_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
254 | | const gx_fill_params *params, |
255 | | const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
256 | 5.47M | { |
257 | 5.47M | if (dev->child) |
258 | 5.47M | return dev_proc(dev->child, fill_path)(dev->child, pgs, ppath, params, pdcolor, pcpath); |
259 | | /* else */ |
260 | 0 | return gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); |
261 | 5.47M | } |
262 | | |
263 | | int default_subclass_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
264 | | const gx_stroke_params *params, |
265 | | const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
266 | 767k | { |
267 | 767k | if (dev->child) |
268 | 767k | return dev_proc(dev->child, stroke_path)(dev->child, pgs, ppath, params, pdcolor, pcpath); |
269 | | /* else */ |
270 | 0 | return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); |
271 | 767k | } |
272 | | |
273 | | int default_subclass_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
274 | | int x, int y, int width, int height, |
275 | | const gx_drawing_color *pdcolor, int depth, |
276 | | gs_logical_operation_t lop, const gx_clip_path *pcpath) |
277 | 0 | { |
278 | 0 | if (dev->child) |
279 | 0 | return dev_proc(dev->child, fill_mask)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); |
280 | | /* else */ |
281 | 0 | return gx_default_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); |
282 | 0 | } |
283 | | |
284 | | int default_subclass_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, |
285 | | fixed ybot, fixed ytop, bool swap_axes, |
286 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop) |
287 | 0 | { |
288 | 0 | if (dev->child) |
289 | 0 | return dev_proc(dev->child, fill_trapezoid)(dev->child, left, right, ybot, ytop, swap_axes, pdcolor, lop); |
290 | | /* else */ |
291 | 0 | return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); |
292 | 0 | } |
293 | | |
294 | | int default_subclass_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
295 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop) |
296 | 0 | { |
297 | 0 | if (dev->child) |
298 | 0 | return dev_proc(dev->child, fill_parallelogram)(dev->child, px, py, ax, ay, bx, by, pdcolor, lop); |
299 | | /* else */ |
300 | 0 | return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop); |
301 | 0 | } |
302 | | |
303 | | int default_subclass_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
304 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop) |
305 | 0 | { |
306 | 0 | if (dev->child) |
307 | 0 | return dev_proc(dev->child, fill_triangle)(dev->child, px, py, ax, ay, bx, by, pdcolor, lop); |
308 | | /* else */ |
309 | 0 | return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop); |
310 | 0 | } |
311 | | |
312 | | int default_subclass_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, |
313 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop, |
314 | | fixed adjustx, fixed adjusty) |
315 | 0 | { |
316 | 0 | if (dev->child) |
317 | 0 | return dev_proc(dev->child, draw_thin_line)(dev->child, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); |
318 | | /* else */ |
319 | 0 | return gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); |
320 | 0 | } |
321 | | |
322 | | int default_subclass_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, |
323 | | gx_color_index color0, gx_color_index color1, |
324 | | int phase_x, int phase_y) |
325 | 0 | { |
326 | 0 | if (dev->child) |
327 | 0 | return dev_proc(dev->child, strip_tile_rectangle)(dev->child, tiles, x, y, width, height, color0, color1, phase_x, phase_y); |
328 | | /* else */ |
329 | 0 | return gx_default_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); |
330 | 0 | } |
331 | | |
332 | | void default_subclass_get_clipping_box(gx_device *dev, gs_fixed_rect *pbox) |
333 | 332 | { |
334 | 332 | if (dev->child) { |
335 | 332 | dev_proc(dev->child, get_clipping_box)(dev->child, pbox); |
336 | 332 | } else |
337 | 0 | gx_default_get_clipping_box(dev, pbox); |
338 | | |
339 | 332 | return; |
340 | 332 | } |
341 | | |
342 | | int default_subclass_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, |
343 | | const gs_image_common_t *pic, const gs_int_rect *prect, |
344 | | const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, |
345 | | gs_memory_t *memory, gx_image_enum_common_t **pinfo) |
346 | 247k | { |
347 | 247k | if (dev->child) |
348 | 247k | return dev_proc(dev->child, begin_typed_image)(dev->child, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); |
349 | | /* else */ |
350 | 0 | return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); |
351 | 247k | } |
352 | | |
353 | | int default_subclass_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, |
354 | | gs_get_bits_params_t *params) |
355 | 0 | { |
356 | 0 | if (dev->child) |
357 | 0 | return dev_proc(dev->child, get_bits_rectangle)(dev->child, prect, params); |
358 | | /* else */ |
359 | 0 | return gx_default_get_bits_rectangle(dev, prect, params); |
360 | 0 | } |
361 | | |
362 | | static void subclass_composite_front_finalize(gx_device *dev) |
363 | 0 | { |
364 | 0 | generic_subclass_data *psubclass_data = (generic_subclass_data *)dev->parent->subclass_data; |
365 | |
|
366 | 0 | dev->parent->child = psubclass_data->pre_composite_device; |
367 | 0 | psubclass_data->saved_finalize_method(dev); |
368 | 0 | } |
369 | | |
370 | | int default_subclass_composite_front(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, |
371 | | gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) |
372 | 0 | { |
373 | 0 | int code = 0; |
374 | 0 | gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte; |
375 | 0 | generic_subclass_data *psubclass_data = (generic_subclass_data *)dev->subclass_data; |
376 | 0 | gx_device *thisdev = dev; |
377 | |
|
378 | 0 | if (dev->child) { |
379 | 0 | code = dev_proc(dev->child, composite)(dev->child, pcdev, pcte, pgs, memory, cdev); |
380 | 0 | if (code < 0) |
381 | 0 | return code; |
382 | | |
383 | 0 | if (gs_is_pdf14trans_compositor(pcte)) { |
384 | 0 | switch(pct->params.pdf14_op) |
385 | 0 | { |
386 | 0 | case PDF14_POP_DEVICE: |
387 | 0 | if (psubclass_data->pre_composite_device != NULL) { |
388 | 0 | if (dev->child) { |
389 | 0 | dev->child->parent = NULL; |
390 | 0 | dev->child->child = NULL; |
391 | 0 | dev->child->finalize = psubclass_data->saved_finalize_method; |
392 | 0 | rc_decrement(dev->child, "default_subclass_composite_front"); |
393 | 0 | } |
394 | 0 | dev->child = psubclass_data->pre_composite_device; |
395 | 0 | psubclass_data->pre_composite_device = NULL; |
396 | 0 | psubclass_data->saved_finalize_method = NULL; |
397 | 0 | while (dev) { |
398 | 0 | memcpy(&(dev->color_info), &(dev->child->color_info), sizeof(gx_device_color_info)); |
399 | 0 | dev->num_planar_planes = dev->child->num_planar_planes; |
400 | 0 | dev = dev->parent; |
401 | 0 | } |
402 | 0 | } |
403 | 0 | break; |
404 | 0 | case PDF14_PUSH_DEVICE: |
405 | | /* *pcdev is always returned containing a device capable of doing |
406 | | * compositing. This may mean it is a new device. If this wants |
407 | | * to be the new 'device' in the graphics state, then code will |
408 | | * return as 1. */ |
409 | 0 | if (code == 1) { |
410 | | /* We want this device to stay ahead of the compositor; the newly created compositor has |
411 | | * inserted itself in front of our child device, so basically we want to replace |
412 | | * our current child with the newly created compositor. I hope ! |
413 | | */ |
414 | 0 | psubclass_data = (generic_subclass_data *)dev->subclass_data; |
415 | 0 | if (psubclass_data == NULL) |
416 | 0 | return_error(gs_error_undefined); |
417 | 0 | psubclass_data->pre_composite_device = dev->child; |
418 | 0 | psubclass_data->saved_finalize_method = (*pcdev)->finalize; |
419 | 0 | (*pcdev)->finalize = subclass_composite_front_finalize; |
420 | |
|
421 | 0 | (*pcdev)->child = dev->child; |
422 | 0 | dev->child = *pcdev; |
423 | 0 | (*pcdev)->parent = dev; |
424 | 0 | while (dev) { |
425 | 0 | memcpy(&dev->color_info, &(*pcdev)->color_info, sizeof(gx_device_color_info)); |
426 | 0 | dev->num_planar_planes = dev->child->num_planar_planes; |
427 | 0 | dev = dev->parent; |
428 | 0 | } |
429 | 0 | } |
430 | 0 | break; |
431 | 0 | default: |
432 | | /* It seems like many operations can result in the pdf14 device altering its color |
433 | | * info, presumably as we push different blending spaces. Ick. In order to stay in sync |
434 | | * any time we have inserted a compositor after this class, we must update the color info |
435 | | * of this device after every operation, in case it changes.... |
436 | | */ |
437 | 0 | if (psubclass_data->pre_composite_device != NULL) { |
438 | 0 | while (dev) { |
439 | 0 | memcpy(&(dev->color_info), &(dev->child->color_info), sizeof(gx_device_color_info)); |
440 | 0 | dev->num_planar_planes = dev->child->num_planar_planes; |
441 | 0 | dev = dev->parent; |
442 | 0 | } |
443 | 0 | } |
444 | 0 | break; |
445 | 0 | } |
446 | |
|
447 | 0 | } |
448 | | /* We are inserting the compositor code after this device, or the compositor |
449 | | * did not create a new compositor. Either way we don't want the compositor code |
450 | | * to think we want to push a new device, so just return this device to the caller. |
451 | | */ |
452 | 0 | *pcdev = thisdev; |
453 | 0 | return 0; |
454 | 0 | } |
455 | 0 | return 0; |
456 | 0 | } |
457 | | |
458 | | int default_subclass_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, |
459 | | gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) |
460 | 114k | { |
461 | 114k | int code; |
462 | | |
463 | 114k | if (dev->child) { |
464 | | /* Some more unpleasantness here. If the child device is a clist, then it will use the first argument |
465 | | * that we pass to access its own data (not unreasonably), so we need to make sure we pass in the |
466 | | * child device. This has some follow on implications detailed below. |
467 | | */ |
468 | 114k | code = dev_proc(dev->child, composite)(dev->child, pcdev, pcte, pgs, memory, cdev); |
469 | 114k | if (code < 0) |
470 | 1 | return code; |
471 | | |
472 | | /* *pcdev is always returned containing a device capable of doing |
473 | | * compositing. This may mean it is a new device. If this wants |
474 | | * to be the new 'device' in the graphics state, then code will |
475 | | * return as 1. */ |
476 | 114k | if (code == 1) { |
477 | | /* The device chain on entry to this function was: |
478 | | * dev(the subclassing device) -> child. |
479 | | * But now we also have: |
480 | | * *pcdev -> child. |
481 | | * Or in some cases: |
482 | | * *pcdev (-> other device)* -> child |
483 | | * Most callers would be happy to make dev->child = *pcdev, |
484 | | * thus giving us: |
485 | | * dev -> *pcdev (-> other device)* ->child |
486 | | * Unfortunately, we are not happy with that. We need to |
487 | | * remain tightly bound to the child. i.e. we are aiming for: |
488 | | * *pcdev (-> other device)* -> dev -> child |
489 | | * Accordingly, we need to move ourselves within the device |
490 | | * chain. |
491 | | */ |
492 | 3.25k | gx_device *penult = *pcdev; |
493 | | |
494 | 3.25k | if (penult == NULL) { |
495 | | /* This should never happen. */ |
496 | 0 | return gs_error_unknownerror; |
497 | 0 | } |
498 | | |
499 | | /* Find the penultimate device. */ |
500 | 9.54k | while (1) { |
501 | 9.54k | gxdso_device_child_request req; |
502 | 9.54k | req.target = penult; |
503 | 9.54k | req.n = 0; |
504 | 9.54k | code = dev_proc(penult, dev_spec_op)(penult, gxdso_device_child, &req, sizeof(req)); |
505 | 9.54k | if (code < 0) |
506 | 0 | return code; |
507 | 9.54k | if (req.target == NULL) { |
508 | | /* Wooah! Where was dev->child? */ |
509 | 0 | return gs_error_unknownerror; |
510 | 0 | } |
511 | 9.54k | if (req.target == dev->child) |
512 | 3.25k | break; /* penult is the parent. */ |
513 | 6.29k | penult = req.target; |
514 | 6.29k | } |
515 | | |
516 | 3.25k | if (penult == NULL) { |
517 | | /* This should never happen. We know that we've just |
518 | | * had a compositor inserted before dev->child, so there |
519 | | * really ought to be one! */ |
520 | 0 | return gs_error_unknownerror; |
521 | 0 | } |
522 | | |
523 | | /* We already point to dev->child, and hence own a reference |
524 | | * to it. */ |
525 | | |
526 | | /* Now insert ourselves as the child of the penultimate one. */ |
527 | 3.25k | code = dev_proc(penult, dev_spec_op)(penult, gxdso_device_insert_child, dev, 0); |
528 | 3.25k | if (code < 0) |
529 | 0 | return code; |
530 | | |
531 | | /* Now we want our caller to update itself to recognise that |
532 | | * *pcdev should be its child, not dev. So we return 1. */ |
533 | 3.25k | return 1; |
534 | 3.25k | } |
535 | 111k | else { |
536 | | /* See the 2 comments above. Now, if the child did not create a new compositor (eg its a clist) |
537 | | * then it returns pcdev pointing to the passed in device (the child in our case). Now this is a |
538 | | * problem, if we return with pcdev == child->dev, and the current device is 'dev' then the |
539 | | * compositor code will think we wanted to push a new device and will select the child device. |
540 | | * so here if pcdev == dev->child we change it to be our own device, so that the calling code |
541 | | * won't redirect the device in the graphics state. |
542 | | */ |
543 | 111k | *pcdev = dev; |
544 | 111k | return code; |
545 | 111k | } |
546 | 114k | } |
547 | 0 | return 0; |
548 | 114k | } |
549 | | |
550 | | int default_subclass_get_hardware_params(gx_device *dev, gs_param_list *plist) |
551 | 0 | { |
552 | 0 | if (dev->child) |
553 | 0 | return dev_proc(dev->child, get_hardware_params)(dev->child, plist); |
554 | | /* else */ |
555 | 0 | return gx_default_get_hardware_params(dev, plist); |
556 | 0 | } |
557 | | |
558 | | int default_subclass_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, |
559 | | gs_font *font, const gx_clip_path *pcpath, |
560 | | gs_text_enum_t **ppte) |
561 | 2.53M | { |
562 | 2.53M | if (dev->child) |
563 | 2.53M | return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, pcpath, ppte); |
564 | | /* else */ |
565 | 0 | return gx_default_text_begin(dev, pgs, text, font, pcpath, ppte); |
566 | 2.53M | } |
567 | | |
568 | | int default_subclass_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, |
569 | | const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) |
570 | 0 | { |
571 | 0 | if (dev->child) |
572 | 0 | return dev_proc(dev->child, begin_transparency_group)(dev->child, ptgp, pbbox, pgs, mem); |
573 | | |
574 | 0 | return 0; |
575 | 0 | } |
576 | | |
577 | | int default_subclass_end_transparency_group(gx_device *dev, gs_gstate *pgs) |
578 | 0 | { |
579 | 0 | if (dev->child) |
580 | 0 | return dev_proc(dev->child, end_transparency_group)(dev->child, pgs); |
581 | | |
582 | 0 | return 0; |
583 | 0 | } |
584 | | |
585 | | int default_subclass_begin_transparency_mask(gx_device *dev, const gx_transparency_mask_params_t *ptmp, |
586 | | const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) |
587 | 0 | { |
588 | 0 | if (dev->child) |
589 | 0 | return dev_proc(dev->child, begin_transparency_mask)(dev->child, ptmp, pbbox, pgs, mem); |
590 | | |
591 | 0 | return 0; |
592 | 0 | } |
593 | | |
594 | | int default_subclass_end_transparency_mask(gx_device *dev, gs_gstate *pgs) |
595 | 0 | { |
596 | 0 | if (dev->child) |
597 | 0 | return dev_proc(dev->child, end_transparency_mask)(dev->child, pgs); |
598 | | |
599 | 0 | return 0; |
600 | 0 | } |
601 | | |
602 | | int default_subclass_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) |
603 | 0 | { |
604 | 0 | if (dev->child) |
605 | 0 | return dev_proc(dev->child, discard_transparency_layer)(dev->child, pgs); |
606 | | |
607 | 0 | return 0; |
608 | 0 | } |
609 | | |
610 | | const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev, |
611 | | const gx_device **tdev) |
612 | 2.82M | { |
613 | 2.82M | if (dev->child) |
614 | 2.82M | return dev_proc(dev->child, get_color_mapping_procs)(dev->child, tdev); |
615 | | /* else */ |
616 | 0 | return gx_default_DevGray_get_color_mapping_procs(dev, tdev); |
617 | 2.82M | } |
618 | | |
619 | | int default_subclass_get_color_comp_index(gx_device *dev, const char * pname, int name_size, int component_type) |
620 | 11.7k | { |
621 | 11.7k | if (dev->child) |
622 | 11.7k | return dev_proc(dev->child, get_color_comp_index)(dev->child, pname, name_size, component_type); |
623 | | /* else */ |
624 | 0 | return gx_error_get_color_comp_index(dev, pname, name_size, component_type); |
625 | 11.7k | } |
626 | | |
627 | | gx_color_index default_subclass_encode_color(gx_device *dev, const gx_color_value colors[]) |
628 | 3.00M | { |
629 | 3.00M | if (dev->child) |
630 | 3.00M | return dev_proc(dev->child, encode_color)(dev->child, colors); |
631 | | /* else */ |
632 | 0 | return gx_error_encode_color(dev, colors); |
633 | 3.00M | } |
634 | | |
635 | | int default_subclass_decode_color(gx_device *dev, gx_color_index cindex, gx_color_value colors[]) |
636 | 0 | { |
637 | 0 | if (dev->child) |
638 | 0 | return dev_proc(dev->child, decode_color)(dev->child, cindex, colors); |
639 | 0 | else { |
640 | 0 | memset(colors, 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); |
641 | 0 | } |
642 | | |
643 | 0 | return 0; |
644 | 0 | } |
645 | | |
646 | | int default_subclass_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, |
647 | | const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
648 | 0 | { |
649 | 0 | if (dev->child) |
650 | 0 | return dev_proc(dev->child, fill_rectangle_hl_color)(dev->child, rect, pgs, pdcolor, pcpath); |
651 | | /* else */ |
652 | 0 | return_error(gs_error_rangecheck); |
653 | 0 | } |
654 | | |
655 | | int default_subclass_include_color_space(gx_device *dev, gs_color_space *cspace, const byte *res_name, int name_length) |
656 | 0 | { |
657 | 0 | if (dev->child) |
658 | 0 | return dev_proc(dev->child, include_color_space)(dev->child, cspace, res_name, name_length); |
659 | | |
660 | 0 | return 0; |
661 | 0 | } |
662 | | |
663 | | int default_subclass_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, |
664 | | int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, |
665 | | int32_t cg_den) |
666 | 0 | { |
667 | 0 | if (dev->child) |
668 | 0 | return dev_proc(dev->child, fill_linear_color_scanline)(dev->child, fa, i, j, w, c0, c0_f, cg_num, cg_den); |
669 | | /* else */ |
670 | 0 | return gx_default_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); |
671 | 0 | } |
672 | | |
673 | | int default_subclass_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, |
674 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
675 | | const gs_fixed_point *p2, const gs_fixed_point *p3, |
676 | | const frac31 *c0, const frac31 *c1, |
677 | | const frac31 *c2, const frac31 *c3) |
678 | 0 | { |
679 | 0 | if (dev->child) |
680 | 0 | return dev_proc(dev->child, fill_linear_color_trapezoid)(dev->child, fa, p0, p1, p2, p3, c0, c1, c2, c3); |
681 | | /* else */ |
682 | 0 | return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); |
683 | 0 | } |
684 | | |
685 | | int default_subclass_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, |
686 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
687 | | const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) |
688 | 0 | { |
689 | 0 | if (dev->child) |
690 | 0 | return dev_proc(dev->child, fill_linear_color_triangle)(dev->child, fa, p0, p1, p2, c0, c1, c2); |
691 | | /* else */ |
692 | 0 | return gx_default_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); |
693 | 0 | } |
694 | | |
695 | | int default_subclass_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs, const gs_color_space *pcs) |
696 | 119 | { |
697 | 119 | if (dev->child) |
698 | 119 | return dev_proc(dev->child, update_spot_equivalent_colors)(dev->child, pgs, pcs); |
699 | | |
700 | 0 | return 0; |
701 | 119 | } |
702 | | |
703 | | gs_devn_params *default_subclass_ret_devn_params(gx_device *dev) |
704 | 6.40k | { |
705 | 6.40k | if (dev->child) |
706 | 6.40k | return dev_proc(dev->child, ret_devn_params)(dev->child); |
707 | | |
708 | 0 | return 0; |
709 | 6.40k | } |
710 | | |
711 | | int default_subclass_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) |
712 | 0 | { |
713 | 0 | if (dev->child) |
714 | 0 | return dev_proc(dev->child, fillpage)(dev->child, pgs, pdevc); |
715 | | /* else */ |
716 | 0 | return gx_default_fillpage(dev, pgs, pdevc); |
717 | 0 | } |
718 | | |
719 | | int default_subclass_push_transparency_state(gx_device *dev, gs_gstate *pgs) |
720 | 0 | { |
721 | 0 | if (dev->child) |
722 | 0 | return dev_proc(dev->child, push_transparency_state)(dev->child, pgs); |
723 | | |
724 | 0 | return 0; |
725 | 0 | } |
726 | | |
727 | | int default_subclass_pop_transparency_state(gx_device *dev, gs_gstate *pgs) |
728 | 0 | { |
729 | 0 | if (dev->child) |
730 | 0 | return dev_proc(dev->child, pop_transparency_state)(dev->child, pgs); |
731 | | |
732 | 0 | return 0; |
733 | 0 | } |
734 | | |
735 | | int default_subclass_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y, |
736 | | int width, int height, int row_stride, |
737 | | int alpha_plane_index, int tag_plane_index) |
738 | 0 | { |
739 | 0 | if (dev->child) { |
740 | 0 | if (dev == mdev) { |
741 | 0 | return dev_proc(dev->child, put_image)(dev->child, dev->child, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); |
742 | 0 | } |
743 | 0 | else { |
744 | 0 | return dev_proc(dev->child, put_image)(dev->child, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); |
745 | 0 | } |
746 | 0 | } |
747 | 0 | return 0; |
748 | 0 | } |
749 | | |
750 | | int default_subclass_dev_spec_op(gx_device *dev, int op, void *data, int datasize) |
751 | 34.7M | { |
752 | 34.7M | if (op == gxdso_is_clist_device) |
753 | 0 | return 0; |
754 | 34.7M | if (op == gxdso_device_child) { |
755 | 0 | gxdso_device_child_request *d = (gxdso_device_child_request *)data; |
756 | 0 | if (d->target == dev) { |
757 | 0 | d->target = dev->child; |
758 | 0 | return 1; |
759 | 0 | } |
760 | 0 | } |
761 | 34.7M | if (dev->child) |
762 | 34.7M | return dev_proc(dev->child, dev_spec_op)(dev->child, op, data, datasize); |
763 | | |
764 | 0 | return 0; |
765 | 34.7M | } |
766 | | |
767 | | int default_subclass_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
768 | | int x, int y, int width, int height, int plane_height) |
769 | 0 | { |
770 | 0 | if (dev->child) |
771 | 0 | return dev_proc(dev->child, copy_planes)(dev->child, data, data_x, raster, id, x, y, width, height, plane_height); |
772 | | |
773 | 0 | return 0; |
774 | 0 | } |
775 | | |
776 | | int default_subclass_get_profile(const gx_device *dev, cmm_dev_profile_t **dev_profile) |
777 | 14.2M | { |
778 | 14.2M | if (dev->child) { |
779 | 14.2M | return dev_proc(dev->child, get_profile)(dev->child, dev_profile); |
780 | 14.2M | } |
781 | | /* else */ |
782 | 0 | return gx_default_get_profile(dev, dev_profile); |
783 | 14.2M | } |
784 | | |
785 | | /* In a delightful asymmetry, we have a set_graphics_type_tag, but no get_graphics_type_tag. Instead |
786 | | * (shudder) the code pulls the currently encoded colour and tag *directly* from the current device. |
787 | | * This means we have to copy the ENCODE_TAGS from the device we are subclassing, into the device which |
788 | | * is newly created at installation time. We also have to have our default set_graphics_type_tag method |
789 | | * update its graphics_type_tag, even though this device has no interest in it, just in case we happen |
790 | | * to be the top device in the chain...... |
791 | | */ |
792 | | |
793 | | void default_subclass_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t tag) |
794 | 902k | { |
795 | | /* |
796 | | * AIUI we should not be calling this method *unless* the ENCODE_TAGS bit is set, so we don't need |
797 | | * to do any checking. Just set the supplied tag in the current device, and pass it on to the underlying |
798 | | * device(s). This line is a direct copy from gx_default_set_graphics_type_tag. |
799 | | */ |
800 | 902k | dev->graphics_type_tag = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) | tag; |
801 | | |
802 | 902k | if (dev->child) |
803 | 902k | dev_proc(dev->child, set_graphics_type_tag)(dev->child, tag); |
804 | | |
805 | 902k | return; |
806 | 902k | } |
807 | | |
808 | | int default_subclass_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, |
809 | | const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, |
810 | | int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) |
811 | 0 | { |
812 | 0 | if (!dev->child) |
813 | 0 | return 0; |
814 | | |
815 | 0 | return dev_proc(dev->child, strip_copy_rop2)(dev->child, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); |
816 | 0 | } |
817 | | |
818 | | int default_subclass_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, |
819 | | const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y) |
820 | 0 | { |
821 | 0 | if (dev->child) |
822 | 0 | return dev_proc(dev->child, strip_tile_rect_devn)(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); |
823 | | /* else */ |
824 | 0 | return gx_default_strip_tile_rect_devn(dev, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); |
825 | 0 | } |
826 | | |
827 | | int default_subclass_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, |
828 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
829 | | const gx_drawing_color *pdcolor, int depth) |
830 | 0 | { |
831 | 0 | if (dev->child) |
832 | 0 | return dev_proc(dev->child, copy_alpha_hl_color)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth); |
833 | | /* else */ |
834 | 0 | return_error(gs_error_rangecheck); |
835 | 0 | } |
836 | | |
837 | | int default_subclass_process_page(gx_device *dev, gx_process_page_options_t *options) |
838 | 0 | { |
839 | 0 | if (dev->child) |
840 | 0 | return dev_proc(dev->child, process_page)(dev->child, options); |
841 | | |
842 | 0 | return 0; |
843 | 0 | } |
844 | | |
845 | | int default_subclass_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
846 | | const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill, |
847 | | const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke, |
848 | | const gx_clip_path *pcpath) |
849 | 11.0k | { |
850 | 11.0k | if (dev->child) |
851 | 11.0k | return dev_proc(dev->child, fill_stroke_path)(dev->child, pgs, ppath, fill_params, pdcolor_fill, |
852 | 11.0k | stroke_params, pdcolor_stroke, pcpath); |
853 | 0 | return 0; |
854 | 11.0k | } |
855 | | |
856 | | int default_subclass_lock_pattern(gx_device *dev, gs_gstate *pgs, gs_id pattern_id, int lock) |
857 | 121 | { |
858 | 121 | if (dev->child) |
859 | 121 | return dev_proc(dev->child, lock_pattern)(dev->child, pgs, pattern_id, lock); |
860 | 0 | return 0; |
861 | 121 | } |
862 | | |
863 | | int default_subclass_transform_pixel_region(gx_device *dev, transform_pixel_region_reason reason, transform_pixel_region_data *data) |
864 | 0 | { |
865 | 0 | if (dev->child) |
866 | 0 | return dev_proc(dev->child, transform_pixel_region)(dev->child, reason, data); |
867 | | |
868 | 0 | return gs_error_unknownerror; |
869 | 0 | } |
870 | | |
871 | | void default_subclass_finalize(const gs_memory_t *cmem, void *vptr) |
872 | 31.6k | { |
873 | 31.6k | gx_device * const dev = (gx_device *)vptr; |
874 | 31.6k | generic_subclass_data *psubclass_data = (generic_subclass_data *)dev->subclass_data; |
875 | 31.6k | (void)cmem; /* unused */ |
876 | | |
877 | 31.6k | discard(gs_closedevice(dev)); |
878 | | |
879 | 31.6k | if (dev->finalize) |
880 | 0 | dev->finalize(dev); |
881 | | |
882 | | /* The only way we should get here is when the original device |
883 | | * should be freed (because the subclassing device is pretending |
884 | | * to be the original device). That being the case, all the child |
885 | | * devices should have a reference count of 1 (referenced only by |
886 | | * their parent). Anything else is an error. |
887 | | */ |
888 | 31.6k | if (dev->child != NULL) { |
889 | 31.6k | if (dev->child->rc.ref_count != 1) { |
890 | 0 | dmprintf(dev->memory, "Error: finalizing subclassing device while child refcount > 1\n"); |
891 | 0 | while (dev->child->rc.ref_count != 1) |
892 | 0 | rc_decrement_only(dev->child, "de-reference child device"); |
893 | 0 | } |
894 | 31.6k | rc_decrement(dev->child, "de-reference child device"); |
895 | 31.6k | } |
896 | | |
897 | 31.6k | if (psubclass_data) { |
898 | 31.6k | gs_free_object(dev->memory->non_gc_memory, psubclass_data, "gx_epo_finalize(suclass data)"); |
899 | 31.6k | dev->subclass_data = NULL; |
900 | 31.6k | } |
901 | 31.6k | if (dev->stype_is_dynamic) |
902 | 31.6k | gs_free_const_object(dev->memory->non_gc_memory, dev->stype, |
903 | 31.6k | "default_subclass_finalize"); |
904 | 31.6k | if (dev->icc_struct) |
905 | 31.6k | rc_decrement(dev->icc_struct, "finalize subclass device"); |
906 | 31.6k | if (dev->PageList) |
907 | 31.6k | rc_decrement(dev->PageList, "finalize subclass device"); |
908 | 31.6k | if (dev->NupControl) |
909 | 31.6k | rc_decrement(dev->NupControl, "finalize subclass device"); |
910 | 31.6k | } |
911 | | |
912 | | void default_subclass_initialize_device_procs(gx_device *dev) |
913 | 31.6k | { |
914 | 31.6k | set_dev_proc(dev, open_device, default_subclass_open_device); |
915 | 31.6k | set_dev_proc(dev, get_initial_matrix, default_subclass_get_initial_matrix); |
916 | 31.6k | set_dev_proc(dev, sync_output, default_subclass_sync_output); |
917 | 31.6k | set_dev_proc(dev, output_page, default_subclass_output_page); |
918 | 31.6k | set_dev_proc(dev, close_device, default_subclass_close_device); |
919 | 31.6k | set_dev_proc(dev, map_rgb_color, default_subclass_map_rgb_color); |
920 | 31.6k | set_dev_proc(dev, map_color_rgb, default_subclass_map_color_rgb); |
921 | 31.6k | set_dev_proc(dev, fill_rectangle, default_subclass_fill_rectangle); |
922 | 31.6k | set_dev_proc(dev, copy_mono, default_subclass_copy_mono); |
923 | 31.6k | set_dev_proc(dev, copy_color, default_subclass_copy_color); |
924 | 31.6k | set_dev_proc(dev, get_params, default_subclass_get_params); |
925 | 31.6k | set_dev_proc(dev, put_params, default_subclass_put_params); |
926 | 31.6k | set_dev_proc(dev, map_cmyk_color, default_subclass_map_cmyk_color); |
927 | 31.6k | set_dev_proc(dev, get_page_device, default_subclass_get_page_device); |
928 | 31.6k | set_dev_proc(dev, get_alpha_bits, default_subclass_get_alpha_bits); |
929 | 31.6k | set_dev_proc(dev, copy_alpha, default_subclass_copy_alpha); |
930 | 31.6k | set_dev_proc(dev, fill_path, default_subclass_fill_path); |
931 | 31.6k | set_dev_proc(dev, stroke_path, default_subclass_stroke_path); |
932 | 31.6k | set_dev_proc(dev, fill_mask, default_subclass_fill_mask); |
933 | 31.6k | set_dev_proc(dev, fill_trapezoid, default_subclass_fill_trapezoid); |
934 | 31.6k | set_dev_proc(dev, fill_parallelogram, default_subclass_fill_parallelogram); |
935 | 31.6k | set_dev_proc(dev, fill_triangle, default_subclass_fill_triangle); |
936 | 31.6k | set_dev_proc(dev, draw_thin_line, default_subclass_draw_thin_line); |
937 | 31.6k | set_dev_proc(dev, strip_tile_rectangle, default_subclass_strip_tile_rectangle); |
938 | 31.6k | set_dev_proc(dev, get_clipping_box, default_subclass_get_clipping_box); |
939 | 31.6k | set_dev_proc(dev, begin_typed_image, default_subclass_begin_typed_image); |
940 | 31.6k | set_dev_proc(dev, get_bits_rectangle, default_subclass_get_bits_rectangle); |
941 | 31.6k | set_dev_proc(dev, composite, default_subclass_composite); |
942 | 31.6k | set_dev_proc(dev, get_hardware_params, default_subclass_get_hardware_params); |
943 | 31.6k | set_dev_proc(dev, text_begin, default_subclass_text_begin); |
944 | 31.6k | set_dev_proc(dev, begin_transparency_group, default_subclass_begin_transparency_group); |
945 | 31.6k | set_dev_proc(dev, end_transparency_group, default_subclass_end_transparency_group); |
946 | 31.6k | set_dev_proc(dev, begin_transparency_mask, default_subclass_begin_transparency_mask); |
947 | 31.6k | set_dev_proc(dev, end_transparency_mask, default_subclass_end_transparency_mask); |
948 | 31.6k | set_dev_proc(dev, discard_transparency_layer, default_subclass_discard_transparency_layer); |
949 | 31.6k | set_dev_proc(dev, get_color_mapping_procs, default_subclass_get_color_mapping_procs); |
950 | 31.6k | set_dev_proc(dev, get_color_comp_index, default_subclass_get_color_comp_index); |
951 | 31.6k | set_dev_proc(dev, encode_color, default_subclass_encode_color); |
952 | 31.6k | set_dev_proc(dev, decode_color, default_subclass_decode_color); |
953 | 31.6k | set_dev_proc(dev, fill_rectangle_hl_color, default_subclass_fill_rectangle_hl_color); |
954 | 31.6k | set_dev_proc(dev, include_color_space, default_subclass_include_color_space); |
955 | 31.6k | set_dev_proc(dev, fill_linear_color_scanline, default_subclass_fill_linear_color_scanline); |
956 | 31.6k | set_dev_proc(dev, fill_linear_color_trapezoid, default_subclass_fill_linear_color_trapezoid); |
957 | 31.6k | set_dev_proc(dev, fill_linear_color_triangle, default_subclass_fill_linear_color_triangle); |
958 | 31.6k | set_dev_proc(dev, update_spot_equivalent_colors, default_subclass_update_spot_equivalent_colors); |
959 | 31.6k | set_dev_proc(dev, ret_devn_params, default_subclass_ret_devn_params); |
960 | 31.6k | set_dev_proc(dev, fillpage, default_subclass_fillpage); |
961 | 31.6k | set_dev_proc(dev, push_transparency_state, default_subclass_push_transparency_state); |
962 | 31.6k | set_dev_proc(dev, pop_transparency_state, default_subclass_pop_transparency_state); |
963 | 31.6k | set_dev_proc(dev, put_image, default_subclass_put_image); |
964 | 31.6k | set_dev_proc(dev, dev_spec_op, default_subclass_dev_spec_op); |
965 | 31.6k | set_dev_proc(dev, copy_planes, default_subclass_copy_planes); |
966 | 31.6k | set_dev_proc(dev, get_profile, default_subclass_get_profile); |
967 | 31.6k | set_dev_proc(dev, set_graphics_type_tag, default_subclass_set_graphics_type_tag); |
968 | 31.6k | set_dev_proc(dev, strip_copy_rop2, default_subclass_strip_copy_rop2); |
969 | 31.6k | set_dev_proc(dev, strip_tile_rect_devn, default_subclass_strip_tile_rect_devn); |
970 | 31.6k | set_dev_proc(dev, copy_alpha_hl_color, default_subclass_copy_alpha_hl_color); |
971 | 31.6k | set_dev_proc(dev, process_page, default_subclass_process_page); |
972 | 31.6k | set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); |
973 | 31.6k | set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); |
974 | 31.6k | set_dev_proc(dev, lock_pattern, default_subclass_lock_pattern); |
975 | 31.6k | } |
976 | | |
977 | | int |
978 | | default_subclass_install(gx_device *dev, gs_gstate *pgs) |
979 | 0 | { |
980 | 0 | dev = dev->child; |
981 | 0 | return dev->page_procs.install(dev, pgs); |
982 | 0 | } |
983 | | |
984 | | int |
985 | | default_subclass_begin_page(gx_device *dev, gs_gstate *pgs) |
986 | 0 | { |
987 | 0 | dev = dev->child; |
988 | 0 | return dev->page_procs.begin_page(dev, pgs); |
989 | 0 | } |
990 | | |
991 | | int |
992 | | default_subclass_end_page(gx_device *dev, int reason, gs_gstate *pgs) |
993 | 0 | { |
994 | 0 | dev = dev->child; |
995 | 0 | return dev->page_procs.end_page(dev, reason, pgs); |
996 | 0 | } |
997 | | |
998 | | void gx_subclass_fill_in_page_procs(gx_device *dev) |
999 | 31.6k | { |
1000 | 31.6k | if (dev->page_procs.install == NULL) |
1001 | 31.6k | dev->page_procs.install = default_subclass_install; |
1002 | 31.6k | if (dev->page_procs.begin_page == NULL) |
1003 | 31.6k | dev->page_procs.begin_page = default_subclass_begin_page; |
1004 | 31.6k | if (dev->page_procs.end_page == NULL) |
1005 | 31.6k | dev->page_procs.end_page = default_subclass_end_page; |
1006 | 31.6k | } |