Coverage Report

Created: 2025-06-24 07:01

/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