/src/ghostpdl/base/gdevsclass.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2022 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, |
13 | | CA 94945, U.S.A., +1(415)492-9861, for further information. |
14 | | */ |
15 | | |
16 | | /* 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 | 0 | { |
116 | 0 | if (dev->child) |
117 | 0 | dev_proc(dev->child, get_initial_matrix)(dev->child, pmat); |
118 | 0 | else |
119 | 0 | gx_default_get_initial_matrix(dev, pmat); |
120 | 0 | return; |
121 | 0 | } |
122 | | |
123 | | int default_subclass_sync_output(gx_device *dev) |
124 | 0 | { |
125 | 0 | if (dev->child) |
126 | 0 | return dev_proc(dev->child, sync_output)(dev->child); |
127 | | /* else */ |
128 | 0 | return gx_default_sync_output(dev); |
129 | 0 | } |
130 | | |
131 | | int default_subclass_output_page(gx_device *dev, int num_copies, int flush) |
132 | 0 | { |
133 | 0 | int code = 0; |
134 | |
|
135 | 0 | if (dev->child) { |
136 | 0 | code = dev_proc(dev->child, output_page)(dev->child, num_copies, flush); |
137 | 0 | dev->PageCount = dev->child->PageCount; |
138 | 0 | return code; |
139 | 0 | } |
140 | 0 | dev->PageCount += num_copies; /* a minor lie */ |
141 | 0 | return 0; |
142 | 0 | } |
143 | | |
144 | | int default_subclass_close_device(gx_device *dev) |
145 | 0 | { |
146 | 0 | int code; |
147 | |
|
148 | 0 | if (dev->child) { |
149 | 0 | code = dev_proc(dev->child, close_device)(dev->child); |
150 | 0 | dev->is_open = dev->child->is_open = false; |
151 | 0 | return code; |
152 | 0 | } |
153 | 0 | dev->is_open = false; |
154 | 0 | return 0; |
155 | 0 | } |
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 | 0 | { |
176 | 0 | if (dev->child) |
177 | 0 | return dev_proc(dev->child, fill_rectangle)(dev->child, x, y, width, height, color); |
178 | 0 | return 0; |
179 | 0 | } |
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 | 0 | { |
200 | 0 | if (dev->child) |
201 | 0 | return dev_proc(dev->child, get_params)(dev->child, plist); |
202 | | /* else */ |
203 | 0 | return gx_default_get_params(dev, plist); |
204 | 0 | } |
205 | | |
206 | | int default_subclass_put_params(gx_device *dev, gs_param_list *plist) |
207 | 0 | { |
208 | 0 | int code; |
209 | |
|
210 | 0 | if (dev->child) { |
211 | 0 | code = dev_proc(dev->child, put_params)(dev->child, plist); |
212 | | /* The child device might have closed itself (yes seriously, this can happen!) */ |
213 | 0 | dev->is_open = dev->child->is_open; |
214 | 0 | gx_update_from_subclass(dev); |
215 | 0 | return code; |
216 | 0 | } |
217 | | /* else */ |
218 | 0 | return gx_default_put_params(dev, plist); |
219 | 0 | } |
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 | 0 | { |
231 | 0 | if (dev->child) |
232 | 0 | return dev_proc(dev->child, get_page_device)(dev->child); |
233 | | /* else */ |
234 | 0 | return gx_default_get_page_device(dev); |
235 | 0 | } |
236 | | |
237 | | int default_subclass_get_alpha_bits(gx_device *dev, graphics_object_type type) |
238 | 0 | { |
239 | 0 | if (dev->child) |
240 | 0 | return dev_proc(dev->child, get_alpha_bits)(dev->child, type); |
241 | 0 | return 0; |
242 | 0 | } |
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 | 0 | { |
257 | 0 | if (dev->child) |
258 | 0 | 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 | 0 | } |
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 | 0 | { |
267 | 0 | if (dev->child) |
268 | 0 | 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 | 0 | } |
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 | 0 | { |
334 | 0 | if (dev->child) { |
335 | 0 | dev_proc(dev->child, get_clipping_box)(dev->child, pbox); |
336 | 0 | } else |
337 | 0 | gx_default_get_clipping_box(dev, pbox); |
338 | |
|
339 | 0 | return; |
340 | 0 | } |
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 | 0 | { |
347 | 0 | if (dev->child) |
348 | 0 | 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 | 0 | } |
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 | | int default_subclass_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, |
363 | | gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) |
364 | 0 | { |
365 | 0 | int code; |
366 | |
|
367 | 0 | if (dev->child) { |
368 | | /* Some more unpleasantness here. If the child device is a clist, then it will use the first argument |
369 | | * that we pass to access its own data (not unreasonably), so we need to make sure we pass in the |
370 | | * child device. This has some follow on implications detailed below. |
371 | | */ |
372 | 0 | code = dev_proc(dev->child, composite)(dev->child, pcdev, pcte, pgs, memory, cdev); |
373 | 0 | if (code < 0) |
374 | 0 | return code; |
375 | | |
376 | | /* *pcdev is always returned containing a device capable of doing |
377 | | * compositing. This may mean it is a new device. If this wants |
378 | | * to be the new 'device' in the graphics state, then code will |
379 | | * return as 1. */ |
380 | 0 | if (code == 1) { |
381 | | /* The device chain on entry to this function was: |
382 | | * dev(the subclassing device) -> child. |
383 | | * But now we also have: |
384 | | * *pcdev -> child. |
385 | | * Or in some cases: |
386 | | * *pcdev (-> other device)* -> child |
387 | | * Most callers would be happy to make dev->child = *pcdev, |
388 | | * thus giving us: |
389 | | * dev -> *pcdev (-> other device)* ->child |
390 | | * Unfortunately, we are not happy with that. We need to |
391 | | * remain tightly bound to the child. i.e. we are aiming for: |
392 | | * *pcdev (-> other device)* -> dev -> child |
393 | | * Accordingly, we need to move ourselves within the device |
394 | | * chain. |
395 | | */ |
396 | 0 | gx_device *penult = *pcdev; |
397 | |
|
398 | 0 | if (penult == NULL) { |
399 | | /* This should never happen. */ |
400 | 0 | return gs_error_unknownerror; |
401 | 0 | } |
402 | | |
403 | | /* Find the penultimate device. */ |
404 | 0 | while (1) { |
405 | 0 | gxdso_device_child_request req; |
406 | 0 | req.target = penult; |
407 | 0 | req.n = 0; |
408 | 0 | code = dev_proc(penult, dev_spec_op)(penult, gxdso_device_child, &req, sizeof(req)); |
409 | 0 | if (code < 0) |
410 | 0 | return code; |
411 | 0 | if (req.target == NULL) { |
412 | | /* Wooah! Where was dev->child? */ |
413 | 0 | return gs_error_unknownerror; |
414 | 0 | } |
415 | 0 | if (req.target == dev->child) |
416 | 0 | break; /* penult is the parent. */ |
417 | 0 | penult = req.target; |
418 | 0 | } |
419 | | |
420 | 0 | if (penult == NULL) { |
421 | | /* This should never happen. We know that we've just |
422 | | * had a compositor inserted before dev->child, so there |
423 | | * really ought to be one! */ |
424 | 0 | return gs_error_unknownerror; |
425 | 0 | } |
426 | | |
427 | | /* We already point to dev->child, and hence own a reference |
428 | | * to it. */ |
429 | | |
430 | | /* Now insert ourselves as the child of the penultimate one. */ |
431 | 0 | code = dev_proc(penult, dev_spec_op)(penult, gxdso_device_insert_child, dev, 0); |
432 | 0 | if (code < 0) |
433 | 0 | return code; |
434 | | |
435 | | /* Now we want our caller to update itself to recognise that |
436 | | * *pcdev should be its child, not dev. So we return 1. */ |
437 | 0 | return 1; |
438 | 0 | } |
439 | 0 | else { |
440 | | /* See the 2 comments above. Now, if the child did not create a new compositor (eg its a clist) |
441 | | * then it returns pcdev pointing to the passed in device (the child in our case). Now this is a |
442 | | * problem, if we return with pcdev == child->dev, and teh current device is 'dev' then the |
443 | | * compositor code will think we wanted to push a new device and will select the child device. |
444 | | * so here if pcdev == dev->child we change it to be our own device, so that the calling code |
445 | | * won't redirect the device in the graphics state. |
446 | | */ |
447 | 0 | *pcdev = dev; |
448 | 0 | return code; |
449 | 0 | } |
450 | 0 | } |
451 | 0 | return 0; |
452 | 0 | } |
453 | | |
454 | | int default_subclass_get_hardware_params(gx_device *dev, gs_param_list *plist) |
455 | 0 | { |
456 | 0 | if (dev->child) |
457 | 0 | return dev_proc(dev->child, get_hardware_params)(dev->child, plist); |
458 | | /* else */ |
459 | 0 | return gx_default_get_hardware_params(dev, plist); |
460 | 0 | } |
461 | | |
462 | | int default_subclass_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, |
463 | | gs_font *font, const gx_clip_path *pcpath, |
464 | | gs_text_enum_t **ppte) |
465 | 0 | { |
466 | 0 | if (dev->child) |
467 | 0 | return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, pcpath, ppte); |
468 | | /* else */ |
469 | 0 | return gx_default_text_begin(dev, pgs, text, font, pcpath, ppte); |
470 | 0 | } |
471 | | |
472 | | int default_subclass_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, |
473 | | const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) |
474 | 0 | { |
475 | 0 | if (dev->child) |
476 | 0 | return dev_proc(dev->child, begin_transparency_group)(dev->child, ptgp, pbbox, pgs, mem); |
477 | | |
478 | 0 | return 0; |
479 | 0 | } |
480 | | |
481 | | int default_subclass_end_transparency_group(gx_device *dev, gs_gstate *pgs) |
482 | 0 | { |
483 | 0 | if (dev->child) |
484 | 0 | return dev_proc(dev->child, end_transparency_group)(dev->child, pgs); |
485 | | |
486 | 0 | return 0; |
487 | 0 | } |
488 | | |
489 | | int default_subclass_begin_transparency_mask(gx_device *dev, const gx_transparency_mask_params_t *ptmp, |
490 | | const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) |
491 | 0 | { |
492 | 0 | if (dev->child) |
493 | 0 | return dev_proc(dev->child, begin_transparency_mask)(dev->child, ptmp, pbbox, pgs, mem); |
494 | | |
495 | 0 | return 0; |
496 | 0 | } |
497 | | |
498 | | int default_subclass_end_transparency_mask(gx_device *dev, gs_gstate *pgs) |
499 | 0 | { |
500 | 0 | if (dev->child) |
501 | 0 | return dev_proc(dev->child, end_transparency_mask)(dev->child, pgs); |
502 | | |
503 | 0 | return 0; |
504 | 0 | } |
505 | | |
506 | | int default_subclass_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) |
507 | 0 | { |
508 | 0 | if (dev->child) |
509 | 0 | return dev_proc(dev->child, discard_transparency_layer)(dev->child, pgs); |
510 | | |
511 | 0 | return 0; |
512 | 0 | } |
513 | | |
514 | | const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev, |
515 | | const gx_device **tdev) |
516 | 0 | { |
517 | 0 | if (dev->child) |
518 | 0 | return dev_proc(dev->child, get_color_mapping_procs)(dev->child, tdev); |
519 | | /* else */ |
520 | 0 | return gx_default_DevGray_get_color_mapping_procs(dev, tdev); |
521 | 0 | } |
522 | | |
523 | | int default_subclass_get_color_comp_index(gx_device *dev, const char * pname, int name_size, int component_type) |
524 | 0 | { |
525 | 0 | if (dev->child) |
526 | 0 | return dev_proc(dev->child, get_color_comp_index)(dev->child, pname, name_size, component_type); |
527 | | /* else */ |
528 | 0 | return gx_error_get_color_comp_index(dev, pname, name_size, component_type); |
529 | 0 | } |
530 | | |
531 | | gx_color_index default_subclass_encode_color(gx_device *dev, const gx_color_value colors[]) |
532 | 0 | { |
533 | 0 | if (dev->child) |
534 | 0 | return dev_proc(dev->child, encode_color)(dev->child, colors); |
535 | | /* else */ |
536 | 0 | return gx_error_encode_color(dev, colors); |
537 | 0 | } |
538 | | |
539 | | int default_subclass_decode_color(gx_device *dev, gx_color_index cindex, gx_color_value colors[]) |
540 | 0 | { |
541 | 0 | if (dev->child) |
542 | 0 | return dev_proc(dev->child, decode_color)(dev->child, cindex, colors); |
543 | 0 | else { |
544 | 0 | memset(colors, 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); |
545 | 0 | } |
546 | | |
547 | 0 | return 0; |
548 | 0 | } |
549 | | |
550 | | int default_subclass_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, |
551 | | const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
552 | 0 | { |
553 | 0 | if (dev->child) |
554 | 0 | return dev_proc(dev->child, fill_rectangle_hl_color)(dev->child, rect, pgs, pdcolor, pcpath); |
555 | | /* else */ |
556 | 0 | return_error(gs_error_rangecheck); |
557 | 0 | } |
558 | | |
559 | | int default_subclass_include_color_space(gx_device *dev, gs_color_space *cspace, const byte *res_name, int name_length) |
560 | 0 | { |
561 | 0 | if (dev->child) |
562 | 0 | return dev_proc(dev->child, include_color_space)(dev->child, cspace, res_name, name_length); |
563 | | |
564 | 0 | return 0; |
565 | 0 | } |
566 | | |
567 | | int default_subclass_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, |
568 | | int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, |
569 | | int32_t cg_den) |
570 | 0 | { |
571 | 0 | if (dev->child) |
572 | 0 | return dev_proc(dev->child, fill_linear_color_scanline)(dev->child, fa, i, j, w, c0, c0_f, cg_num, cg_den); |
573 | | /* else */ |
574 | 0 | return gx_default_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); |
575 | 0 | } |
576 | | |
577 | | int default_subclass_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, |
578 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
579 | | const gs_fixed_point *p2, const gs_fixed_point *p3, |
580 | | const frac31 *c0, const frac31 *c1, |
581 | | const frac31 *c2, const frac31 *c3) |
582 | 0 | { |
583 | 0 | if (dev->child) |
584 | 0 | return dev_proc(dev->child, fill_linear_color_trapezoid)(dev->child, fa, p0, p1, p2, p3, c0, c1, c2, c3); |
585 | | /* else */ |
586 | 0 | return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); |
587 | 0 | } |
588 | | |
589 | | int default_subclass_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, |
590 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
591 | | const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) |
592 | 0 | { |
593 | 0 | if (dev->child) |
594 | 0 | return dev_proc(dev->child, fill_linear_color_triangle)(dev->child, fa, p0, p1, p2, c0, c1, c2); |
595 | | /* else */ |
596 | 0 | return gx_default_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); |
597 | 0 | } |
598 | | |
599 | | int default_subclass_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs, const gs_color_space *pcs) |
600 | 0 | { |
601 | 0 | if (dev->child) |
602 | 0 | return dev_proc(dev->child, update_spot_equivalent_colors)(dev->child, pgs, pcs); |
603 | | |
604 | 0 | return 0; |
605 | 0 | } |
606 | | |
607 | | gs_devn_params *default_subclass_ret_devn_params(gx_device *dev) |
608 | 0 | { |
609 | 0 | if (dev->child) |
610 | 0 | return dev_proc(dev->child, ret_devn_params)(dev->child); |
611 | | |
612 | 0 | return 0; |
613 | 0 | } |
614 | | |
615 | | int default_subclass_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) |
616 | 0 | { |
617 | 0 | if (dev->child) |
618 | 0 | return dev_proc(dev->child, fillpage)(dev->child, pgs, pdevc); |
619 | | /* else */ |
620 | 0 | return gx_default_fillpage(dev, pgs, pdevc); |
621 | 0 | } |
622 | | |
623 | | int default_subclass_push_transparency_state(gx_device *dev, gs_gstate *pgs) |
624 | 0 | { |
625 | 0 | if (dev->child) |
626 | 0 | return dev_proc(dev->child, push_transparency_state)(dev->child, pgs); |
627 | | |
628 | 0 | return 0; |
629 | 0 | } |
630 | | |
631 | | int default_subclass_pop_transparency_state(gx_device *dev, gs_gstate *pgs) |
632 | 0 | { |
633 | 0 | if (dev->child) |
634 | 0 | return dev_proc(dev->child, pop_transparency_state)(dev->child, pgs); |
635 | | |
636 | 0 | return 0; |
637 | 0 | } |
638 | | |
639 | | int default_subclass_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y, |
640 | | int width, int height, int row_stride, |
641 | | int alpha_plane_index, int tag_plane_index) |
642 | 0 | { |
643 | 0 | if (dev->child) { |
644 | 0 | if (dev == mdev) { |
645 | 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); |
646 | 0 | } |
647 | 0 | else { |
648 | 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); |
649 | 0 | } |
650 | 0 | } |
651 | 0 | return 0; |
652 | 0 | } |
653 | | |
654 | | int default_subclass_dev_spec_op(gx_device *dev, int op, void *data, int datasize) |
655 | 0 | { |
656 | 0 | if (op == gxdso_is_clist_device) |
657 | 0 | return 0; |
658 | 0 | if (op == gxdso_device_child) { |
659 | 0 | gxdso_device_child_request *d = (gxdso_device_child_request *)data; |
660 | 0 | if (d->target == dev) { |
661 | 0 | d->target = dev->child; |
662 | 0 | return 1; |
663 | 0 | } |
664 | 0 | } |
665 | 0 | if (dev->child) |
666 | 0 | return dev_proc(dev->child, dev_spec_op)(dev->child, op, data, datasize); |
667 | | |
668 | 0 | return 0; |
669 | 0 | } |
670 | | |
671 | | int default_subclass_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
672 | | int x, int y, int width, int height, int plane_height) |
673 | 0 | { |
674 | 0 | if (dev->child) |
675 | 0 | return dev_proc(dev->child, copy_planes)(dev->child, data, data_x, raster, id, x, y, width, height, plane_height); |
676 | | |
677 | 0 | return 0; |
678 | 0 | } |
679 | | |
680 | | int default_subclass_get_profile(const gx_device *dev, cmm_dev_profile_t **dev_profile) |
681 | 0 | { |
682 | 0 | if (dev->child) { |
683 | 0 | return dev_proc(dev->child, get_profile)(dev->child, dev_profile); |
684 | 0 | } |
685 | | /* else */ |
686 | 0 | return gx_default_get_profile(dev, dev_profile); |
687 | 0 | } |
688 | | |
689 | | /* In a delightful asymmetry, we have a set_graphics_type_tag, but no get_graphics_type_tag. Instead |
690 | | * (shudder) the code pulls the currently encoded colour and tag *directly* from the current device. |
691 | | * This means we have to copy the ENCODE_TAGS from the device we are subclassing, into the device which |
692 | | * is newly created at installation time. We also have to have our default set_graphics_type_tag method |
693 | | * update its graphics_type_tag, even though this device has no interest in it, just in case we happen |
694 | | * to be the top device in the chain...... |
695 | | */ |
696 | | |
697 | | void default_subclass_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t tag) |
698 | 0 | { |
699 | | /* |
700 | | * AIUI we should not be calling this method *unless* the ENCODE_TAGS bit is set, so we don't need |
701 | | * to do any checking. Just set the supplied tag in the current device, and pass it on to the underlying |
702 | | * device(s). This line is a direct copy from gx_default_set_graphics_type_tag. |
703 | | */ |
704 | 0 | dev->graphics_type_tag = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) | tag; |
705 | |
|
706 | 0 | if (dev->child) |
707 | 0 | dev_proc(dev->child, set_graphics_type_tag)(dev->child, tag); |
708 | |
|
709 | 0 | return; |
710 | 0 | } |
711 | | |
712 | | int default_subclass_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, |
713 | | const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, |
714 | | int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) |
715 | 0 | { |
716 | 0 | if (!dev->child) |
717 | 0 | return 0; |
718 | | |
719 | 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); |
720 | 0 | } |
721 | | |
722 | | int default_subclass_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, |
723 | | const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y) |
724 | 0 | { |
725 | 0 | if (dev->child) |
726 | 0 | return dev_proc(dev->child, strip_tile_rect_devn)(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); |
727 | | /* else */ |
728 | 0 | return gx_default_strip_tile_rect_devn(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); |
729 | 0 | } |
730 | | |
731 | | int default_subclass_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, |
732 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
733 | | const gx_drawing_color *pdcolor, int depth) |
734 | 0 | { |
735 | 0 | if (dev->child) |
736 | 0 | return dev_proc(dev->child, copy_alpha_hl_color)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth); |
737 | | /* else */ |
738 | 0 | return_error(gs_error_rangecheck); |
739 | 0 | } |
740 | | |
741 | | int default_subclass_process_page(gx_device *dev, gx_process_page_options_t *options) |
742 | 0 | { |
743 | 0 | if (dev->child) |
744 | 0 | return dev_proc(dev->child, process_page)(dev->child, options); |
745 | | |
746 | 0 | return 0; |
747 | 0 | } |
748 | | |
749 | | int default_subclass_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
750 | | const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill, |
751 | | const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke, |
752 | | const gx_clip_path *pcpath) |
753 | 0 | { |
754 | 0 | if (dev->child) |
755 | 0 | return dev_proc(dev->child, fill_stroke_path)(dev->child, pgs, ppath, fill_params, pdcolor_fill, |
756 | 0 | stroke_params, pdcolor_stroke, pcpath); |
757 | 0 | return 0; |
758 | 0 | } |
759 | | |
760 | | int default_subclass_lock_pattern(gx_device *dev, gs_gstate *pgs, gs_id pattern_id, int lock) |
761 | 0 | { |
762 | 0 | if (dev->child) |
763 | 0 | return dev_proc(dev->child, lock_pattern)(dev->child, pgs, pattern_id, lock); |
764 | 0 | return 0; |
765 | 0 | } |
766 | | |
767 | | int default_subclass_transform_pixel_region(gx_device *dev, transform_pixel_region_reason reason, transform_pixel_region_data *data) |
768 | 0 | { |
769 | 0 | if (dev->child) |
770 | 0 | return dev_proc(dev->child, transform_pixel_region)(dev->child, reason, data); |
771 | | |
772 | 0 | return gs_error_unknownerror; |
773 | 0 | } |
774 | | |
775 | | void default_subclass_finalize(const gs_memory_t *cmem, void *vptr) |
776 | 0 | { |
777 | 0 | gx_device * const dev = (gx_device *)vptr; |
778 | 0 | generic_subclass_data *psubclass_data = (generic_subclass_data *)dev->subclass_data; |
779 | 0 | (void)cmem; /* unused */ |
780 | |
|
781 | 0 | discard(gs_closedevice(dev)); |
782 | |
|
783 | 0 | if (dev->finalize) |
784 | 0 | dev->finalize(dev); |
785 | |
|
786 | 0 | if (psubclass_data) { |
787 | 0 | gs_free_object(dev->memory->non_gc_memory, psubclass_data, "gx_epo_finalize(suclass data)"); |
788 | 0 | dev->subclass_data = NULL; |
789 | 0 | } |
790 | 0 | if (dev->child) { |
791 | 0 | gs_free_object(dev->memory->stable_memory, dev->child, "free child device memory for subclassing device"); |
792 | 0 | } |
793 | 0 | if (dev->stype_is_dynamic) |
794 | 0 | gs_free_const_object(dev->memory->non_gc_memory, dev->stype, |
795 | 0 | "default_subclass_finalize"); |
796 | 0 | if (dev->parent) |
797 | 0 | dev->parent->child = dev->child; |
798 | 0 | if (dev->child) |
799 | 0 | dev->child->parent = dev->parent; |
800 | 0 | if (dev->icc_struct) |
801 | 0 | rc_decrement(dev->icc_struct, "finalize subclass device"); |
802 | 0 | if (dev->PageList) |
803 | 0 | rc_decrement(dev->PageList, "finalize subclass device"); |
804 | 0 | if (dev->NupControl) |
805 | 0 | rc_decrement(dev->NupControl, "finalize subclass device"); |
806 | 0 | } |
807 | | |
808 | | void default_subclass_initialize_device_procs(gx_device *dev) |
809 | 0 | { |
810 | 0 | set_dev_proc(dev, open_device, default_subclass_open_device); |
811 | 0 | set_dev_proc(dev, get_initial_matrix, default_subclass_get_initial_matrix); |
812 | 0 | set_dev_proc(dev, sync_output, default_subclass_sync_output); |
813 | 0 | set_dev_proc(dev, output_page, default_subclass_output_page); |
814 | 0 | set_dev_proc(dev, close_device, default_subclass_close_device); |
815 | 0 | set_dev_proc(dev, map_rgb_color, default_subclass_map_rgb_color); |
816 | 0 | set_dev_proc(dev, map_color_rgb, default_subclass_map_color_rgb); |
817 | 0 | set_dev_proc(dev, fill_rectangle, default_subclass_fill_rectangle); |
818 | 0 | set_dev_proc(dev, copy_mono, default_subclass_copy_mono); |
819 | 0 | set_dev_proc(dev, copy_color, default_subclass_copy_color); |
820 | 0 | set_dev_proc(dev, get_params, default_subclass_get_params); |
821 | 0 | set_dev_proc(dev, put_params, default_subclass_put_params); |
822 | 0 | set_dev_proc(dev, map_cmyk_color, default_subclass_map_cmyk_color); |
823 | 0 | set_dev_proc(dev, get_page_device, default_subclass_get_page_device); |
824 | 0 | set_dev_proc(dev, get_alpha_bits, default_subclass_get_alpha_bits); |
825 | 0 | set_dev_proc(dev, copy_alpha, default_subclass_copy_alpha); |
826 | 0 | set_dev_proc(dev, fill_path, default_subclass_fill_path); |
827 | 0 | set_dev_proc(dev, stroke_path, default_subclass_stroke_path); |
828 | 0 | set_dev_proc(dev, fill_mask, default_subclass_fill_mask); |
829 | 0 | set_dev_proc(dev, fill_trapezoid, default_subclass_fill_trapezoid); |
830 | 0 | set_dev_proc(dev, fill_parallelogram, default_subclass_fill_parallelogram); |
831 | 0 | set_dev_proc(dev, fill_triangle, default_subclass_fill_triangle); |
832 | 0 | set_dev_proc(dev, draw_thin_line, default_subclass_draw_thin_line); |
833 | 0 | set_dev_proc(dev, strip_tile_rectangle, default_subclass_strip_tile_rectangle); |
834 | 0 | set_dev_proc(dev, get_clipping_box, default_subclass_get_clipping_box); |
835 | 0 | set_dev_proc(dev, begin_typed_image, default_subclass_begin_typed_image); |
836 | 0 | set_dev_proc(dev, get_bits_rectangle, default_subclass_get_bits_rectangle); |
837 | 0 | set_dev_proc(dev, composite, default_subclass_composite); |
838 | 0 | set_dev_proc(dev, get_hardware_params, default_subclass_get_hardware_params); |
839 | 0 | set_dev_proc(dev, text_begin, default_subclass_text_begin); |
840 | 0 | set_dev_proc(dev, begin_transparency_group, default_subclass_begin_transparency_group); |
841 | 0 | set_dev_proc(dev, end_transparency_group, default_subclass_end_transparency_group); |
842 | 0 | set_dev_proc(dev, begin_transparency_mask, default_subclass_begin_transparency_mask); |
843 | 0 | set_dev_proc(dev, end_transparency_mask, default_subclass_end_transparency_mask); |
844 | 0 | set_dev_proc(dev, discard_transparency_layer, default_subclass_discard_transparency_layer); |
845 | 0 | set_dev_proc(dev, get_color_mapping_procs, default_subclass_get_color_mapping_procs); |
846 | 0 | set_dev_proc(dev, get_color_comp_index, default_subclass_get_color_comp_index); |
847 | 0 | set_dev_proc(dev, encode_color, default_subclass_encode_color); |
848 | 0 | set_dev_proc(dev, decode_color, default_subclass_decode_color); |
849 | 0 | set_dev_proc(dev, fill_rectangle_hl_color, default_subclass_fill_rectangle_hl_color); |
850 | 0 | set_dev_proc(dev, include_color_space, default_subclass_include_color_space); |
851 | 0 | set_dev_proc(dev, fill_linear_color_scanline, default_subclass_fill_linear_color_scanline); |
852 | 0 | set_dev_proc(dev, fill_linear_color_trapezoid, default_subclass_fill_linear_color_trapezoid); |
853 | 0 | set_dev_proc(dev, fill_linear_color_triangle, default_subclass_fill_linear_color_triangle); |
854 | 0 | set_dev_proc(dev, update_spot_equivalent_colors, default_subclass_update_spot_equivalent_colors); |
855 | 0 | set_dev_proc(dev, ret_devn_params, default_subclass_ret_devn_params); |
856 | 0 | set_dev_proc(dev, fillpage, default_subclass_fillpage); |
857 | 0 | set_dev_proc(dev, push_transparency_state, default_subclass_push_transparency_state); |
858 | 0 | set_dev_proc(dev, pop_transparency_state, default_subclass_pop_transparency_state); |
859 | 0 | set_dev_proc(dev, put_image, default_subclass_put_image); |
860 | 0 | set_dev_proc(dev, dev_spec_op, default_subclass_dev_spec_op); |
861 | 0 | set_dev_proc(dev, copy_planes, default_subclass_copy_planes); |
862 | 0 | set_dev_proc(dev, get_profile, default_subclass_get_profile); |
863 | 0 | set_dev_proc(dev, set_graphics_type_tag, default_subclass_set_graphics_type_tag); |
864 | 0 | set_dev_proc(dev, strip_copy_rop2, default_subclass_strip_copy_rop2); |
865 | 0 | set_dev_proc(dev, strip_tile_rect_devn, default_subclass_strip_tile_rect_devn); |
866 | 0 | set_dev_proc(dev, copy_alpha_hl_color, default_subclass_copy_alpha_hl_color); |
867 | 0 | set_dev_proc(dev, process_page, default_subclass_process_page); |
868 | 0 | set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); |
869 | 0 | set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); |
870 | 0 | set_dev_proc(dev, lock_pattern, default_subclass_lock_pattern); |
871 | 0 | } |
872 | | |
873 | | int |
874 | | default_subclass_install(gx_device *dev, gs_gstate *pgs) |
875 | 0 | { |
876 | 0 | dev = dev->child; |
877 | 0 | return dev->page_procs.install(dev, pgs); |
878 | 0 | } |
879 | | |
880 | | int |
881 | | default_subclass_begin_page(gx_device *dev, gs_gstate *pgs) |
882 | 0 | { |
883 | 0 | dev = dev->child; |
884 | 0 | return dev->page_procs.begin_page(dev, pgs); |
885 | 0 | } |
886 | | |
887 | | int |
888 | | default_subclass_end_page(gx_device *dev, int reason, gs_gstate *pgs) |
889 | 0 | { |
890 | 0 | dev = dev->child; |
891 | 0 | return dev->page_procs.end_page(dev, reason, pgs); |
892 | 0 | } |
893 | | |
894 | | void gx_subclass_fill_in_page_procs(gx_device *dev) |
895 | 0 | { |
896 | 0 | if (dev->page_procs.install == NULL) |
897 | 0 | dev->page_procs.install = default_subclass_install; |
898 | 0 | if (dev->page_procs.begin_page == NULL) |
899 | 0 | dev->page_procs.begin_page = default_subclass_begin_page; |
900 | 0 | if (dev->page_procs.end_page == NULL) |
901 | 0 | dev->page_procs.end_page = default_subclass_end_page; |
902 | 0 | } |