Coverage Report

Created: 2026-07-24 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevoflt.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 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, code = 0;
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
    code = 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
    if (code < 0) {
315
0
        gs_free_object(memory, pie, "flp_begin_image");
316
0
        *pinfo = NULL;
317
0
        return code;
318
0
    }
319
320
0
    pie->memory = memory;
321
0
    pie->skipping = true;
322
0
    pie->height = pim->Height;
323
0
    pie->mask_y = pie->y = 0;
324
0
    pie->type = pic->type->index;
325
326
0
    if (pic->type->index == 3) {
327
0
        const gs_image3_t *pim = (const gs_image3_t *)pic;
328
329
0
        switch (pim->InterleaveType)
330
0
        {
331
0
            case interleave_chunky:
332
                /* Add the mask data to the depth of the image data. */
333
0
                pie->num_planes = 1;
334
0
                break;
335
0
            case interleave_scan_lines:
336
                /*
337
                 * There is only 1 plane, with dynamically changing width & depth.
338
                 * Initialize it for the mask data, since that is what will be
339
                 * read first.
340
                 */
341
0
                pie->num_planes = 1;
342
0
                pie->plane_depths[0] = 1;
343
0
                pie->plane_widths[0] = pim->MaskDict.Width;
344
0
                break;
345
0
            case interleave_separate_source:
346
                /* Insert the mask data as a separate plane before the image data. */
347
0
                pie->num_planes = 2;
348
0
                pie->plane_depths[1] = pie->plane_depths[0];
349
0
                pie->plane_widths[1] = pie->plane_widths[0];
350
0
                pie->plane_widths[0] = pim->MaskDict.Width;
351
0
                pie->plane_depths[0] = 1;
352
0
                pie->mask_height = pim->MaskDict.Height;
353
0
                break;
354
0
        }
355
0
        pie->InterleaveType = pim->InterleaveType;
356
0
    }
357
0
    if (pic->type->index == IMAGE3X_IMAGETYPE) {
358
0
        const gs_image3x_t *pim = (const gs_image3x_t *)pic;
359
360
0
        if (pim->Opacity.MaskDict.BitsPerComponent != 0) {
361
0
            switch(pim->Opacity.InterleaveType) {
362
0
            case interleave_separate_source:
363
0
                pie->num_planes++;
364
0
                pie->plane_depths[1] = pie->plane_depths[0];
365
0
                pie->plane_widths[1] = pie->plane_widths[0];
366
0
                pie->plane_depths[0] = pim->Opacity.MaskDict.BitsPerComponent;
367
0
                pie->plane_widths[0] = pim->Opacity.MaskDict.Width;
368
0
                break;
369
0
            case interleave_chunky:
370
0
                pie->plane_depths[0] += pim->BitsPerComponent;
371
0
                break;
372
0
            default:    /* can't happen */
373
0
                return_error(gs_error_Fatal);
374
0
            }
375
0
        }
376
0
        if (pim->Shape.MaskDict.BitsPerComponent != 0) {
377
0
            switch(pim->Shape.InterleaveType) {
378
0
            case interleave_separate_source:
379
0
                pie->num_planes++;
380
0
                pie->plane_depths[1] = pie->plane_depths[0];
381
0
                pie->plane_widths[1] = pie->plane_widths[0];
382
0
                pie->plane_depths[0] = pim->Shape.MaskDict.BitsPerComponent;
383
0
                pie->plane_widths[0] = pim->Shape.MaskDict.Width;
384
0
                break;
385
0
            case interleave_chunky:
386
0
                pie->plane_depths[0] += pim->BitsPerComponent;
387
0
                break;
388
0
            default:    /* can't happen */
389
0
                return_error(gs_error_Fatal);
390
0
            }
391
0
        }
392
0
    }
393
0
    return 0;
394
0
}
395
396
/* Text processing (like images) works differently to other device
397
 * methods. Instead of the interpreter calling a device method, only
398
 * the 'begin' method is called, this creates a text enumerator which
399
 * it fills in (in part with the routines for processing text) and returns
400
 * to the interpreter. The interpreter then calls the methods defined in
401
 * the text enumerator to process the text.
402
 * Mad as a fish.....
403
 */
404
405
/* For our purposes if we are handling the text its because we are not
406
 * printing the page, so we cna afford to ignore all the text processing.
407
 * A more complex device might need to define real handlers for these, and
408
 * pass them on to the subclassed device.
409
 */
410
static text_enum_proc_process(obj_filter_text_process);
411
static int
412
obj_filter_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom)
413
0
{
414
0
    return 0;
415
0
}
416
int
417
obj_filter_text_process(gs_text_enum_t *pte)
418
0
{
419
0
    return 0;
420
0
}
421
static bool
422
obj_filter_text_is_width_only(const gs_text_enum_t *pte)
423
0
{
424
0
    return false;
425
0
}
426
static int
427
obj_filter_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth)
428
0
{
429
0
    return 0;
430
0
}
431
static int
432
obj_filter_text_set_cache(gs_text_enum_t *pte, const double *pw,
433
                   gs_text_cache_control_t control)
434
0
{
435
0
    return 0;
436
0
}
437
static int
438
obj_filter_text_retry(gs_text_enum_t *pte)
439
0
{
440
0
    return 0;
441
0
}
442
static void
443
obj_filter_text_release(gs_text_enum_t *pte, client_name_t cname)
444
0
{
445
0
    gx_default_text_release(pte, cname);
446
0
}
447
448
static const gs_text_enum_procs_t obj_filter_text_procs = {
449
    obj_filter_text_resync, obj_filter_text_process,
450
    obj_filter_text_is_width_only, obj_filter_text_current_width,
451
    obj_filter_text_set_cache, obj_filter_text_retry,
452
    obj_filter_text_release
453
};
454
455
/* The device method which we do actually need to define. Either we are skipping the page,
456
 * in which case we create a text enumerator with our dummy procedures, or we are leaving it
457
 * up to the device, in which case we simply pass on the 'begin' method to the device.
458
 */
459
int obj_filter_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text,
460
    gs_font *font, const gx_clip_path *pcpath,
461
    gs_text_enum_t **ppte)
462
0
{
463
0
    obj_filter_text_enum_t *penum;
464
0
    int code = 0;
465
0
    gs_memory_t * memory = pgs->memory;
466
467
    /* We don't want to simply ignore stringwidth for 2 reasons;
468
     * firstly because following elelments may be positioned based on the value returned
469
     * secondly  because op_show_restore executes an unconditional grestore, assuming
470
     * that a gsave has been done simply *because* its a tringwidth operation !
471
     */
472
0
    if ((text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH) && pgs->text_rendering_mode != 3)
473
        /* Note that the high level devices *must* be given the opportunity to 'see' the
474
         * stringwidth operation, or they won;t be able to cache the glyphs properly.
475
         * So always pass stringwidth operations to the child.
476
         */
477
0
        return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte);
478
479
0
    if ((dev->ObjectFilter & FILTERTEXT) == 0)
480
0
        return default_subclass_text_begin(dev, pgs, text, font, pcpath, ppte);
481
482
0
    rc_alloc_struct_1(penum, obj_filter_text_enum_t, &st_obj_filter_text_enum, memory,
483
0
                  return_error(gs_error_VMerror), "gdev_obj_filter_text_begin");
484
0
    penum->rc.free = rc_free_text_enum;
485
0
    code = gs_text_enum_init((gs_text_enum_t *)penum, &obj_filter_text_procs,
486
0
                         dev, pgs, text, font, pcpath, memory);
487
0
    if (code < 0) {
488
0
        gs_free_object(memory, penum, "gdev_obj_filter_text_begin");
489
0
        return code;
490
0
    }
491
0
    *ppte = (gs_text_enum_t *)penum;
492
493
0
    return 0;
494
0
}
495
496
int obj_filter_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
497
        const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath)
498
0
{
499
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
500
0
        return default_subclass_fill_rectangle_hl_color(dev, rect, pgs, pdcolor, pcpath);
501
0
    return 0;
502
0
}
503
504
int obj_filter_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa,
505
        int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num,
506
        int32_t cg_den)
507
0
{
508
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
509
0
        return default_subclass_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den);
510
0
    return 0;
511
0
}
512
513
int obj_filter_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa,
514
        const gs_fixed_point *p0, const gs_fixed_point *p1,
515
        const gs_fixed_point *p2, const gs_fixed_point *p3,
516
        const frac31 *c0, const frac31 *c1,
517
        const frac31 *c2, const frac31 *c3)
518
0
{
519
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
520
0
        return default_subclass_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3);
521
0
    return 0;
522
0
}
523
524
int obj_filter_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa,
525
        const gs_fixed_point *p0, const gs_fixed_point *p1,
526
        const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2)
527
0
{
528
0
    if ((dev->ObjectFilter & FILTERVECTOR) == 0)
529
0
        return default_subclass_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2);
530
0
    return 0;
531
0
}
532
533
int obj_filter_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,
534
            int width, int height, int row_stride,
535
            int alpha_plane_index, int tag_plane_index)
536
0
{
537
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
538
0
        return default_subclass_put_image(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
539
0
    return 0;
540
0
}
541
542
int obj_filter_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id,
543
    const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors,
544
    int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height)
545
0
{
546
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
547
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);
548
0
    return 0;
549
0
}
550
551
int obj_filter_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height,
552
    const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y)
553
0
{
554
0
    if ((dev->ObjectFilter & FILTERIMAGE) == 0)
555
0
        return default_subclass_strip_tile_rect_devn(dev, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y);
556
0
    return 0;
557
0
}