Coverage Report

Created: 2025-06-10 07:06

/src/ghostpdl/base/gdevoflt.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
/* Derived from gdevflp.c */
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 "gximage.h"        /* For gx_image_enum */
35
#include "gximag3x.h"
36
#include "gdevsclass.h"
37
#include "gdevoflt.h"
38
#include "gximag3x.h"
39
40
int gs_is_pdf14trans_compositor(const gs_composite_t * pct);
41
42
/* GC descriptor */
43
public_st_device_obj_filter();
44
/* we need text and image enumerators, because of the crazy way that text and images work */
45
private_st_obj_filter_text_enum();
46
47
/* Device procedures, we need to implement all of them */
48
static dev_proc_fill_rectangle(obj_filter_fill_rectangle);
49
static dev_proc_fill_path(obj_filter_fill_path);
50
static dev_proc_stroke_path(obj_filter_stroke_path);
51
static dev_proc_fill_mask(obj_filter_fill_mask);
52
static dev_proc_fill_trapezoid(obj_filter_fill_trapezoid);
53
static dev_proc_fill_parallelogram(obj_filter_fill_parallelogram);
54
static dev_proc_fill_triangle(obj_filter_fill_triangle);
55
static dev_proc_draw_thin_line(obj_filter_draw_thin_line);
56
static dev_proc_strip_tile_rectangle(obj_filter_strip_tile_rectangle);
57
static dev_proc_begin_typed_image(obj_filter_begin_typed_image);
58
static dev_proc_text_begin(obj_filter_text_begin);
59
static dev_proc_fill_rectangle_hl_color(obj_filter_fill_rectangle_hl_color);
60
static dev_proc_fill_linear_color_scanline(obj_filter_fill_linear_color_scanline);
61
static dev_proc_fill_linear_color_trapezoid(obj_filter_fill_linear_color_trapezoid);
62
static dev_proc_fill_linear_color_triangle(obj_filter_fill_linear_color_triangle);
63
static dev_proc_put_image(obj_filter_put_image);
64
static dev_proc_strip_copy_rop2(obj_filter_strip_copy_rop2);
65
static dev_proc_strip_tile_rect_devn(obj_filter_strip_tile_rect_devn);
66
static dev_proc_fill_stroke_path(obj_filter_fill_stroke_path);
67
68
/* The device prototype */
69
#define MAX_COORD (max_int_in_fixed - 1000)
70
#define MAX_RESOLUTION 4000
71
72
#define public_st_obj_filter_device() /* in gsdevice.c */\
73
  gs_public_st_complex_only(st_obj_filter_device, gx_device, "object filter",\
74
    0, obj_filter_enum_ptrs, obj_filter_reloc_ptrs, default_subclass_finalize)
75
76
static
77
0
ENUM_PTRS_WITH(obj_filter_enum_ptrs, gx_device *dev);
78
0
return 0; /* default case */
79
0
case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent));
80
0
case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child));
81
0
ENUM_PTRS_END
82
0
static RELOC_PTRS_WITH(obj_filter_reloc_ptrs, gx_device *dev)
83
0
{
84
0
    dev->parent = gx_device_reloc_ptr(dev->parent, gcst);
85
0
    dev->child = gx_device_reloc_ptr(dev->child, gcst);
86
0
}
87
0
RELOC_PTRS_END
88
89
public_st_obj_filter_device();
90
91
static void
92
obj_filter_initialize_device_procs(gx_device *dev)
93
0
{
94
0
    default_subclass_initialize_device_procs(dev);
95
96
0
    set_dev_proc(dev, fill_rectangle, obj_filter_fill_rectangle);
97
0
    set_dev_proc(dev, fill_path, obj_filter_fill_path);
98
0
    set_dev_proc(dev, stroke_path, obj_filter_stroke_path);
99
0
    set_dev_proc(dev, fill_mask, obj_filter_fill_mask);
100
0
    set_dev_proc(dev, fill_trapezoid, obj_filter_fill_trapezoid);
101
0
    set_dev_proc(dev, fill_parallelogram, obj_filter_fill_parallelogram);
102
0
    set_dev_proc(dev, fill_triangle, obj_filter_fill_triangle);
103
0
    set_dev_proc(dev, draw_thin_line, obj_filter_draw_thin_line);
104
0
    set_dev_proc(dev, strip_tile_rectangle, obj_filter_strip_tile_rectangle);
105
0
    set_dev_proc(dev, begin_typed_image, obj_filter_begin_typed_image);
106
0
    set_dev_proc(dev, text_begin, obj_filter_text_begin);
107
0
    set_dev_proc(dev, fill_rectangle_hl_color, obj_filter_fill_rectangle_hl_color);
108
0
    set_dev_proc(dev, fill_linear_color_scanline, obj_filter_fill_linear_color_scanline);
109
0
    set_dev_proc(dev, fill_linear_color_trapezoid, obj_filter_fill_linear_color_trapezoid);
110
0
    set_dev_proc(dev, fill_linear_color_triangle, obj_filter_fill_linear_color_triangle);
111
0
    set_dev_proc(dev, put_image, obj_filter_put_image);
112
0
    set_dev_proc(dev, strip_copy_rop2, obj_filter_strip_copy_rop2);
113
0
    set_dev_proc(dev, strip_tile_rect_devn, obj_filter_strip_tile_rect_devn);
114
0
    set_dev_proc(dev, fill_stroke_path, obj_filter_fill_stroke_path);
115
0
    set_dev_proc(dev, composite, default_subclass_composite_front);
116
0
}
117
118
const
119
gx_device_obj_filter gs_obj_filter_device =
120
{
121
    /*
122
     * Define the device as 8-bit gray scale to avoid computing halftones.
123
     */
124
    std_device_dci_type_body_sc(gx_device_obj_filter,
125
                        obj_filter_initialize_device_procs,
126
                        "object_filter", &st_obj_filter_device,
127
                        MAX_COORD, MAX_COORD,
128
                        MAX_RESOLUTION, MAX_RESOLUTION,
129
                        1, 8, 255, 0, 256, 1, NULL, NULL, NULL)
130
};
131
132
#undef MAX_COORD
133
#undef MAX_RESOLUTION
134
135
int obj_filter_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color)
136
0
{
137
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
138
0
        return default_subclass_fill_rectangle(dev, x, y, width, height, color);
139
0
    return 0;
140
0
}
141
142
int obj_filter_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
143
    const gx_fill_params *params,
144
    const gx_drawing_color *pdcolor, const gx_clip_path *pcpath)
145
0
{
146
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
147
0
        return default_subclass_fill_path(dev, pgs, ppath, params, pdcolor, pcpath);
148
0
    return 0;
149
0
}
150
151
int obj_filter_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
152
    const gx_stroke_params *params,
153
    const gx_drawing_color *pdcolor, const gx_clip_path *pcpath)
154
0
{
155
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
156
0
        return default_subclass_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath);
157
0
    return 0;
158
0
}
159
160
int obj_filter_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath,
161
        const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
162
        const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
163
        const gx_clip_path *pcpath)
164
0
{
165
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
166
0
        return default_subclass_fill_stroke_path(dev, pgs, ppath, fill_params, pdcolor_fill, stroke_params, pdcolor_stroke, pcpath);
167
0
    return 0;
168
0
}
169
170
int obj_filter_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id,
171
    int x, int y, int width, int height,
172
    const gx_drawing_color *pdcolor, int depth,
173
    gs_logical_operation_t lop, const gx_clip_path *pcpath)
174
0
{
175
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
176
0
        return default_subclass_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath);
177
0
    return 0;
178
0
}
179
180
int obj_filter_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right,
181
    fixed ybot, fixed ytop, bool swap_axes,
182
    const gx_drawing_color *pdcolor, gs_logical_operation_t lop)
183
0
{
184
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
185
0
        return default_subclass_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop);
186
0
    return 0;
187
0
}
188
189
int obj_filter_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by,
190
    const gx_drawing_color *pdcolor, gs_logical_operation_t lop)
191
0
{
192
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
193
0
        return default_subclass_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop);
194
0
    return 0;
195
0
}
196
197
int obj_filter_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by,
198
    const gx_drawing_color *pdcolor, gs_logical_operation_t lop)
199
0
{
200
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
201
0
        return default_subclass_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop);
202
0
    return 0;
203
0
}
204
205
int obj_filter_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1,
206
    const gx_drawing_color *pdcolor, gs_logical_operation_t lop,
207
    fixed adjustx, fixed adjusty)
208
0
{
209
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
210
0
        return default_subclass_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty);
211
0
    return 0;
212
0
}
213
214
int obj_filter_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height,
215
    gx_color_index color0, gx_color_index color1,
216
    int phase_x, int phase_y)
217
0
{
218
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
219
0
        return default_subclass_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y);
220
0
    return 0;
221
0
}
222
223
typedef struct obj_filter_image_enum_s {
224
    gx_image_enum_common;
225
    int y, mask_y;
226
    int height, mask_height;
227
    int type;
228
    int InterleaveType;
229
} obj_filter_image_enum;
230
gs_private_st_composite(st_obj_filter_image_enum, obj_filter_image_enum, "obj_filter_image_enum",
231
  obj_filter_image_enum_enum_ptrs, obj_filter_image_enum_reloc_ptrs);
232
233
0
static ENUM_PTRS_WITH(obj_filter_image_enum_enum_ptrs, obj_filter_image_enum *pie)
234
0
    (void)pie; /* Silence unused var warning */
235
0
    return ENUM_USING_PREFIX(st_gx_image_enum_common, 0);
236
0
ENUM_PTRS_END
237
0
static RELOC_PTRS_WITH(obj_filter_image_enum_reloc_ptrs, obj_filter_image_enum *pie)
238
0
{
239
0
    (void)pie; /* Silence unused var warning */
240
0
    RELOC_USING(st_gx_image_enum_common, vptr, size);
241
0
}
242
0
RELOC_PTRS_END
243
244
static int
245
obj_filter_image_plane_data(gx_image_enum_common_t * info,
246
                     const gx_image_plane_t * planes, int height,
247
                     int *rows_used)
248
0
{
249
0
    obj_filter_image_enum *pie = (obj_filter_image_enum *)info;
250
251
0
    if (pie->type == 3 && pie->InterleaveType == interleave_separate_source) {
252
0
        pie->y += height;
253
0
        pie->mask_y += height;
254
0
        *rows_used = height;
255
256
0
        if (pie->y < pie->height || pie->mask_y < pie->mask_height)
257
0
            return 0;
258
0
        return 1;
259
0
    } else {
260
0
        if (height > pie->height - pie->y)
261
0
            height = pie->height - pie->y;
262
263
0
        pie->y += height;
264
0
        *rows_used = height;
265
266
0
        if (pie->y < pie->height)
267
0
            return 0;
268
0
        return 1;
269
0
    }
270
0
}
271
272
static int
273
obj_filter_image_end_image(gx_image_enum_common_t * info, bool draw_last)
274
0
{
275
0
    return 0;
276
0
}
277
278
static const gx_image_enum_procs_t obj_filter_image_enum_procs = {
279
    obj_filter_image_plane_data,
280
    obj_filter_image_end_image
281
};
282
283
int obj_filter_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat,
284
    const gs_image_common_t *pic, const gs_int_rect *prect,
285
    const gx_drawing_color *pdcolor, const gx_clip_path *pcpath,
286
    gs_memory_t *memory, gx_image_enum_common_t **pinfo)
287
0
{
288
0
    obj_filter_image_enum *pie;
289
0
    const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic;
290
0
    int num_components;
291
292
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
293
0
        return default_subclass_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo);
294
295
0
    if (pic->type->index == 1) {
296
0
        const gs_image_t *pim1 = (const gs_image_t *)pic;
297
298
0
        if (pim1->ImageMask)
299
0
            num_components = 1;
300
0
        else
301
0
            num_components = gs_color_space_num_components(pim->ColorSpace);
302
0
    } else {
303
0
        num_components = gs_color_space_num_components(pim->ColorSpace);
304
0
    }
305
306
0
    pie = gs_alloc_struct(memory, obj_filter_image_enum, &st_obj_filter_image_enum,
307
0
                        "obj_filter_begin_image");
308
0
    if (pie == 0)
309
0
        return_error(gs_error_VMerror);
310
0
    memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
311
0
    *pinfo = (gx_image_enum_common_t *) pie;
312
0
    gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim, &obj_filter_image_enum_procs,
313
0
                        (gx_device *)dev, num_components, pim->format);
314
0
    pie->memory = memory;
315
0
    pie->skipping = true;
316
0
    pie->height = pim->Height;
317
0
    pie->mask_y = pie->y = 0;
318
0
    pie->type = pic->type->index;
319
320
0
    if (pic->type->index == 3) {
321
0
        const gs_image3_t *pim = (const gs_image3_t *)pic;
322
323
0
        switch (pim->InterleaveType)
324
0
        {
325
0
            case interleave_chunky:
326
                /* Add the mask data to the depth of the image data. */
327
0
                pie->num_planes = 1;
328
0
                break;
329
0
            case interleave_scan_lines:
330
                /*
331
                 * There is only 1 plane, with dynamically changing width & depth.
332
                 * Initialize it for the mask data, since that is what will be
333
                 * read first.
334
                 */
335
0
                pie->num_planes = 1;
336
0
                pie->plane_depths[0] = 1;
337
0
                pie->plane_widths[0] = pim->MaskDict.Width;
338
0
                break;
339
0
            case interleave_separate_source:
340
                /* Insert the mask data as a separate plane before the image data. */
341
0
                pie->num_planes = 2;
342
0
                pie->plane_depths[1] = pie->plane_depths[0];
343
0
                pie->plane_widths[1] = pie->plane_widths[0];
344
0
                pie->plane_widths[0] = pim->MaskDict.Width;
345
0
                pie->plane_depths[0] = 1;
346
0
                pie->mask_height = pim->MaskDict.Height;
347
0
                break;
348
0
        }
349
0
        pie->InterleaveType = pim->InterleaveType;
350
0
    }
351
0
    if (pic->type->index == IMAGE3X_IMAGETYPE) {
352
0
        const gs_image3x_t *pim = (const gs_image3x_t *)pic;
353
354
0
        if (pim->Opacity.MaskDict.BitsPerComponent != 0) {
355
0
            switch(pim->Opacity.InterleaveType) {
356
0
            case interleave_separate_source:
357
0
                pie->num_planes++;
358
0
                pie->plane_depths[1] = pie->plane_depths[0];
359
0
                pie->plane_widths[1] = pie->plane_widths[0];
360
0
                pie->plane_depths[0] = pim->Opacity.MaskDict.BitsPerComponent;
361
0
                pie->plane_widths[0] = pim->Opacity.MaskDict.Width;
362
0
                break;
363
0
            case interleave_chunky:
364
0
                pie->plane_depths[0] += pim->BitsPerComponent;
365
0
                break;
366
0
            default:    /* can't happen */
367
0
                return_error(gs_error_Fatal);
368
0
            }
369
0
        }
370
0
        if (pim->Shape.MaskDict.BitsPerComponent != 0) {
371
0
            switch(pim->Shape.InterleaveType) {
372
0
            case interleave_separate_source:
373
0
                pie->num_planes++;
374
0
                pie->plane_depths[1] = pie->plane_depths[0];
375
0
                pie->plane_widths[1] = pie->plane_widths[0];
376
0
                pie->plane_depths[0] = pim->Shape.MaskDict.BitsPerComponent;
377
0
                pie->plane_widths[0] = pim->Shape.MaskDict.Width;
378
0
                break;
379
0
            case interleave_chunky:
380
0
                pie->plane_depths[0] += pim->BitsPerComponent;
381
0
                break;
382
0
            default:    /* can't happen */
383
0
                return_error(gs_error_Fatal);
384
0
            }
385
0
        }
386
0
    }
387
0
    return 0;
388
0
}
389
390
/* Text processing (like images) works differently to other device
391
 * methods. Instead of the interpreter calling a device method, only
392
 * the 'begin' method is called, this creates a text enumerator which
393
 * it fills in (in part with the routines for processing text) and returns
394
 * to the interpreter. The interpreter then calls the methods defined in
395
 * the text enumerator to process the text.
396
 * Mad as a fish.....
397
 */
398
399
/* For our purposes if we are handling the text its because we are not
400
 * printing the page, so we cna afford to ignore all the text processing.
401
 * A more complex device might need to define real handlers for these, and
402
 * pass them on to the subclassed device.
403
 */
404
static text_enum_proc_process(obj_filter_text_process);
405
static int
406
obj_filter_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
407
0
{
408
0
    return 0;
409
0
}
410
int
411
obj_filter_text_process(gs_text_enum_t *pte)
412
0
{
413
0
    return 0;
414
0
}
415
static bool
416
obj_filter_text_is_width_only(const gs_text_enum_t *pte)
417
0
{
418
0
    return false;
419
0
}
420
static int
421
obj_filter_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
422
0
{
423
0
    return 0;
424
0
}
425
static int
426
obj_filter_text_set_cache(gs_text_enum_t *pte, const double *pw,
427
                   gs_text_cache_control_t control)
428
0
{
429
0
    return 0;
430
0
}
431
static int
432
obj_filter_text_retry(gs_text_enum_t *pte)
433
0
{
434
0
    return 0;
435
0
}
436
static void
437
obj_filter_text_release(gs_text_enum_t *pte, client_name_t cname)
438
0
{
439
0
    gx_default_text_release(pte, cname);
440
0
}
441
442
static const gs_text_enum_procs_t obj_filter_text_procs = {
443
    obj_filter_text_resync, obj_filter_text_process,
444
    obj_filter_text_is_width_only, obj_filter_text_current_width,
445
    obj_filter_text_set_cache, obj_filter_text_retry,
446
    obj_filter_text_release
447
};
448
449
/* The device method which we do actually need to define. Either we are skipping the page,
450
 * in which case we create a text enumerator with our dummy procedures, or we are leaving it
451
 * up to the device, in which case we simply pass on the 'begin' method to the device.
452
 */
453
int obj_filter_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text,
454
    gs_font *font, const gx_clip_path *pcpath,
455
    gs_text_enum_t **ppte)
456
0
{
457
0
    obj_filter_text_enum_t *penum;
458
0
    int code = 0;
459
0
    gs_memory_t * memory = pgs->memory;
460
461
    /* We don't want to simply ignore stringwidth for 2 reasons;
462
     * firstly because following elelments may be positioned based on the value returned
463
     * secondly  because op_show_restore executes an unconditional grestore, assuming
464
     * that a gsave has been done simply *because* its a tringwidth operation !
465
     */
466
0
    if ((text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH) && pgs->text_rendering_mode != 3)
467
        /* Note that the high level devices *must* be given the opportunity to 'see' the
468
         * stringwidth operation, or they won;t be able to cache the glyphs properly.
469
         * So always pass stringwidth operations to the child.
470
         */
471
0
        return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte);
472
473
0
    if ((dev->ObjectFilter & FILTERTEXT) == 0)
474
0
        return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte);
475
476
0
    rc_alloc_struct_1(penum, obj_filter_text_enum_t, &st_obj_filter_text_enum, memory,
477
0
                  return_error(gs_error_VMerror), "gdev_obj_filter_text_begin");
478
0
    penum->rc.free = rc_free_text_enum;
479
0
    code = gs_text_enum_init((gs_text_enum_t *)penum, &obj_filter_text_procs,
480
0
                         dev, pgs, text, font, pcpath, memory);
481
0
    if (code < 0) {
482
0
        gs_free_object(memory, penum, "gdev_obj_filter_text_begin");
483
0
        return code;
484
0
    }
485
0
    *ppte = (gs_text_enum_t *)penum;
486
487
0
    return 0;
488
0
}
489
490
int obj_filter_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
491
        const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath)
492
0
{
493
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
494
0
        return default_subclass_fill_rectangle_hl_color(dev, rect, pgs, pdcolor, pcpath);
495
0
    return 0;
496
0
}
497
498
int obj_filter_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
499
        int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num,
500
        int32_t cg_den)
501
0
{
502
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
503
0
        return default_subclass_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den);
504
0
    return 0;
505
0
}
506
507
int obj_filter_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa,
508
        const gs_fixed_point *p0, const gs_fixed_point *p1,
509
        const gs_fixed_point *p2, const gs_fixed_point *p3,
510
        const frac31 *c0, const frac31 *c1,
511
        const frac31 *c2, const frac31 *c3)
512
0
{
513
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
514
0
        return default_subclass_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3);
515
0
    return 0;
516
0
}
517
518
int obj_filter_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa,
519
        const gs_fixed_point *p0, const gs_fixed_point *p1,
520
        const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2)
521
0
{
522
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
523
0
        return default_subclass_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2);
524
0
    return 0;
525
0
}
526
527
int obj_filter_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,
528
            int width, int height, int row_stride,
529
            int alpha_plane_index, int tag_plane_index)
530
0
{
531
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
532
0
        return default_subclass_put_image(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
533
0
    return 0;
534
0
}
535
536
int obj_filter_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id,
537
    const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors,
538
    int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height)
539
0
{
540
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
541
0
        return default_subclass_strip_copy_rop2(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height);
542
0
    return 0;
543
0
}
544
545
int obj_filter_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height,
546
    const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y)
547
0
{
548
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
549
0
        return default_subclass_strip_tile_rect_devn(dev, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y);
550
0
    return 0;
551
0
}