Coverage Report

Created: 2025-06-10 07:19

/src/ghostpdl/base/gxclipm.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
17
/* Mask clipping device */
18
#include "memory_.h"
19
#include "gx.h"
20
#include "gsbittab.h"
21
#include "gxdevice.h"
22
#include "gxdevmem.h"
23
#include "gxclipm.h"
24
#include "gxdcolor.h"
25
26
/* Device procedures */
27
static dev_proc_fill_rectangle(mask_clip_fill_rectangle);
28
static dev_proc_fill_rectangle_hl_color(mask_clip_fill_rectangle_hl_color);
29
static dev_proc_copy_mono(mask_clip_copy_mono);
30
static dev_proc_copy_color(mask_clip_copy_color);
31
static dev_proc_copy_alpha(mask_clip_copy_alpha);
32
static dev_proc_copy_alpha_hl_color(mask_clip_copy_alpha_hl_color);
33
static dev_proc_strip_tile_rectangle(mask_clip_strip_tile_rectangle);
34
static dev_proc_strip_tile_rect_devn(mask_clip_strip_tile_rect_devn);
35
static dev_proc_strip_copy_rop2(mask_clip_strip_copy_rop2);
36
static dev_proc_get_clipping_box(mask_clip_get_clipping_box);
37
38
/* The device descriptor. */
39
40
static void
41
mask_clip_initialize_device_procs(gx_device *dev)
42
30
{
43
30
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
44
30
    set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color);
45
30
    set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb);
46
30
    set_dev_proc(dev, fill_rectangle, mask_clip_fill_rectangle);
47
30
    set_dev_proc(dev, copy_mono, mask_clip_copy_mono);
48
30
    set_dev_proc(dev, copy_color, mask_clip_copy_color);
49
30
    set_dev_proc(dev, get_params, gx_forward_get_params);
50
30
    set_dev_proc(dev, put_params, gx_forward_put_params);
51
30
    set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color);
52
30
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
53
30
    set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits);
54
30
    set_dev_proc(dev, copy_alpha, mask_clip_copy_alpha);
55
30
    set_dev_proc(dev, strip_tile_rectangle, mask_clip_strip_tile_rectangle);
56
30
    set_dev_proc(dev, get_clipping_box, mask_clip_get_clipping_box);
57
30
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
58
30
    set_dev_proc(dev, composite, gx_no_composite);
59
30
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
60
30
    set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs);
61
30
    set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index);
62
30
    set_dev_proc(dev, encode_color, gx_forward_encode_color);
63
30
    set_dev_proc(dev, decode_color, gx_forward_decode_color);
64
30
    set_dev_proc(dev, fill_rectangle_hl_color, mask_clip_fill_rectangle_hl_color);
65
30
    set_dev_proc(dev, include_color_space, gx_forward_include_color_space);
66
30
    set_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline);
67
30
    set_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid);
68
30
    set_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle);
69
30
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
70
30
    set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params);
71
30
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
72
30
    set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op);
73
30
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
74
30
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
75
30
    set_dev_proc(dev, strip_copy_rop2, mask_clip_strip_copy_rop2);
76
30
    set_dev_proc(dev, strip_tile_rect_devn, mask_clip_strip_tile_rect_devn);
77
30
    set_dev_proc(dev, copy_alpha_hl_color, mask_clip_copy_alpha_hl_color);
78
30
    set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region);
79
30
    set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path);
80
30
    set_dev_proc(dev, lock_pattern, gx_forward_lock_pattern);
81
82
    /* Ideally these defaults would be set up automatically for us. */
83
30
    set_dev_proc(dev, open_device, gx_default_open_device);
84
30
    set_dev_proc(dev, sync_output, gx_default_sync_output);
85
30
    set_dev_proc(dev, output_page, gx_default_output_page);
86
30
    set_dev_proc(dev, close_device, gx_default_close_device);
87
30
    set_dev_proc(dev, fill_path, gx_default_fill_path);
88
30
    set_dev_proc(dev, stroke_path, gx_default_stroke_path);
89
30
    set_dev_proc(dev, fill_mask, gx_default_fill_mask);
90
30
    set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid);
91
30
    set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram);
92
30
    set_dev_proc(dev, fill_triangle, gx_default_fill_triangle);
93
30
    set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line);
94
30
    set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image);
95
30
    set_dev_proc(dev, text_begin, gx_default_text_begin);
96
97
30
 }
98
99
const gx_device_mask_clip gs_mask_clip_device =
100
{std_device_std_body_open(gx_device_mask_clip,
101
                          mask_clip_initialize_device_procs,
102
                          "mask clipper",
103
                          0, 0, 1, 1)
104
};
105
106
/* Fill a rectangle with a hl color, painting through the mask */
107
static int
108
mask_clip_fill_rectangle_hl_color(gx_device *dev,
109
    const gs_fixed_rect *rect,
110
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
111
    const gx_clip_path *pcpath)
112
0
{
113
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
114
0
    gx_device *tdev = cdev->target;
115
0
    int x, y, w, h;
116
0
    int mx0, mx1, my0, my1;
117
118
0
    x = fixed2int(rect->p.x);
119
0
    y = fixed2int(rect->p.y);
120
0
    w = fixed2int(rect->q.x) - x;
121
0
    h = fixed2int(rect->q.y) - y;
122
123
    /* Clip the rectangle to the region covered by the mask. */
124
0
    mx0 = x + cdev->phase.x;
125
0
    my0 = y + cdev->phase.y;
126
0
    mx1 = mx0 + w;
127
0
    my1 = my0 + h;
128
129
0
    if (mx0 < 0)
130
0
        mx0 = 0;
131
0
    if (my0 < 0)
132
0
        my0 = 0;
133
0
    if (mx1 > cdev->tiles.size.x)
134
0
        mx1 = cdev->tiles.size.x;
135
0
    if (my1 > cdev->tiles.size.y)
136
0
        my1 = cdev->tiles.size.y;
137
    /* It would be nice to have a higher level way to do this operation
138
       like a copy_mono_hl_color */
139
0
    return (pdcolor->type->fill_masked)
140
0
            (pdcolor, cdev->tiles.data + my0 * cdev->tiles.raster, mx0,
141
0
             cdev->tiles.raster, cdev->tiles.id, mx0 - cdev->phase.x,
142
0
             my0 - cdev->phase.y, mx1 - mx0, my1 - my0,
143
0
             tdev, lop_default, false);
144
0
}
145
146
/* Fill a rectangle by painting through the mask. */
147
static int
148
mask_clip_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
149
                         gx_color_index color)
150
33.7k
{
151
33.7k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
152
33.7k
    gx_device *tdev = cdev->target;
153
154
    /* Clip the rectangle to the region covered by the mask. */
155
33.7k
    int mx0 = x + cdev->phase.x, my0 = y + cdev->phase.y;
156
33.7k
    int mx1 = mx0 + w, my1 = my0 + h;
157
158
33.7k
    if (mx0 < 0)
159
0
        mx0 = 0;
160
33.7k
    if (my0 < 0)
161
0
        my0 = 0;
162
33.7k
    if (mx1 > cdev->tiles.size.x)
163
0
        mx1 = cdev->tiles.size.x;
164
33.7k
    if (my1 > cdev->tiles.size.y)
165
0
        my1 = cdev->tiles.size.y;
166
33.7k
    return (*dev_proc(tdev, copy_mono))
167
33.7k
        (tdev, cdev->tiles.data + my0 * cdev->tiles.raster, mx0,
168
33.7k
         cdev->tiles.raster, cdev->tiles.id,
169
33.7k
         mx0 - cdev->phase.x, my0 - cdev->phase.y,
170
33.7k
         mx1 - mx0, my1 - my0, gx_no_color_index, color);
171
33.7k
}
172
173
/*
174
 * Clip the rectangle for a copy operation.
175
 * Sets m{x,y}{0,1} to the region in the mask coordinate system;
176
 * subtract cdev->phase.{x,y} to get target coordinates.
177
 * Sets sdata, sx to adjusted values of data, sourcex.
178
 * References cdev, data, sourcex, raster, x, y, w, h.
179
 */
180
#define DECLARE_MASK_COPY\
181
93.7k
        const byte *sdata;\
182
93.7k
        int sx, mx0, my0, mx1, my1
183
#define FIT_MASK_COPY(data, sourcex, raster, vx, vy, vw, vh)\
184
93.7k
        BEGIN\
185
93.7k
          sdata = data, sx = sourcex;\
186
93.7k
          mx0 = vx + cdev->phase.x, my0 = vy + cdev->phase.y;\
187
93.7k
          mx1 = mx0 + vw, my1 = my0 + vh;\
188
93.7k
          if ( mx0 < 0 )\
189
93.7k
            sx -= mx0, mx0 = 0;\
190
93.7k
          if ( my0 < 0 )\
191
93.7k
            sdata -= my0 * raster, my0 = 0;\
192
93.7k
          if ( mx1 > cdev->tiles.size.x )\
193
93.7k
            mx1 = cdev->tiles.size.x;\
194
93.7k
          if ( my1 > cdev->tiles.size.y )\
195
93.7k
            my1 = cdev->tiles.size.y;\
196
93.7k
        END
197
198
/* Copy a monochrome bitmap by playing Boolean games. */
199
static int
200
mask_clip_copy_mono(gx_device * dev,
201
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
202
                    int x, int y, int w, int h,
203
                    gx_color_index color0, gx_color_index color1)
204
0
{
205
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
206
0
    gx_device *tdev = cdev->target;
207
0
    gx_color_index color, mcolor0, mcolor1;
208
209
0
    DECLARE_MASK_COPY;
210
0
    int cy, ny;
211
0
    int code;
212
213
0
    setup_mask_copy_mono(cdev, color, mcolor0, mcolor1);
214
0
    FIT_MASK_COPY(data, sourcex, raster, x, y, w, h);
215
0
    for (cy = my0; cy < my1; cy += ny) {
216
0
        int ty = cy - cdev->phase.y;
217
0
        int cx, nx;
218
219
0
        ny = my1 - cy;
220
0
        if (ny > cdev->mdev.height)
221
0
            ny = cdev->mdev.height;
222
0
        for (cx = mx0; cx < mx1; cx += nx) {
223
0
            int tx = cx - cdev->phase.x;
224
225
0
            nx = mx1 - cx;  /* also should be min */
226
            /* Copy a tile slice to the memory device buffer. */
227
0
            memcpy(cdev->buffer.bytes,
228
0
                   cdev->tiles.data + cy * cdev->tiles.raster,
229
0
                   (size_t)cdev->tiles.raster * ny);
230
            /* Intersect the tile with the source data. */
231
            /* mcolor0 and mcolor1 invert the data if needed. */
232
            /* This call can't fail. */
233
0
            (*dev_proc(&cdev->mdev, copy_mono)) ((gx_device *) & cdev->mdev,
234
0
                                     sdata + (ty - y) * raster, sx + tx - x,
235
0
                                                 raster, gx_no_bitmap_id,
236
0
                                           cx, 0, nx, ny, mcolor0, mcolor1);
237
            /* Now copy the color through the double mask. */
238
0
            code = (*dev_proc(tdev, copy_mono)) (cdev->target,
239
0
                                 cdev->buffer.bytes, cx, cdev->tiles.raster,
240
0
                                                 gx_no_bitmap_id,
241
0
                                  tx, ty, nx, ny, gx_no_color_index, color);
242
0
            if (code < 0)
243
0
                return code;
244
0
        }
245
0
    }
246
0
    return 0;
247
0
}
248
249
#ifdef PACIFY_VALGRIND
250
static inline byte trim(int cx, int mx1, byte v)
251
496k
{
252
496k
    int mask = 8-(mx1-cx); /* mask < 8 */
253
496k
    mask = (mask > 0 ? (0xff<<mask) : 0xff)>>(cx & 7);
254
496k
    return v & mask;
255
496k
}
256
#else
257
#define trim(cx,mx1,v) (v)
258
#endif
259
260
/*
261
 * Define the run enumerator for the other copying operations.  We can't use
262
 * the BitBlt tricks: we have to scan for runs of 1s.  There are obvious
263
 * ways to speed this up; we'll implement some if we need to.
264
 */
265
static int
266
clip_runs_enumerate(gx_device_mask_clip * cdev,
267
                    int (*process) (clip_callback_data_t * pccd, int xc, int yc, int xec, int yec),
268
                    clip_callback_data_t * pccd)
269
93.7k
{
270
93.7k
    DECLARE_MASK_COPY;
271
93.7k
    int cy;
272
93.7k
    const byte *tile_row;
273
93.7k
    gs_int_rect prev;
274
93.7k
    int code;
275
276
93.7k
    FIT_MASK_COPY(pccd->data, pccd->sourcex, pccd->raster,
277
93.7k
                  pccd->x, pccd->y, pccd->w, pccd->h);
278
93.7k
    tile_row = cdev->tiles.data + my0 * cdev->tiles.raster + (mx0 >> 3);
279
93.7k
    prev.p.x = 0; /* arbitrary */
280
93.7k
    prev.q.x = prev.p.x - 1;  /* an impossible rectangle */
281
93.7k
    prev.p.y = prev.q.y = -1; /* arbitrary */
282
200k
    for (cy = my0; cy < my1; cy++) {
283
107k
        int cx = mx0;
284
107k
        const byte *tp = tile_row;
285
286
107k
        if_debug1m('B', cdev->memory, "[B]clip runs y=%d:", cy - cdev->phase.y);
287
145k
        while (cx < mx1) {
288
118k
            int len;
289
118k
            int tx1, tx, ty;
290
291
            /* Skip a run of 0s. */
292
118k
            len = byte_bit_run_length[cx & 7][trim(cx, mx1, *tp) ^ 0xff];
293
118k
            if (len < 8) {
294
29.8k
                cx += len;
295
29.8k
                if (cx >= mx1)
296
0
                    break;
297
88.1k
            } else {
298
88.1k
                cx += len - 8;
299
88.1k
                tp++;
300
351k
                while (cx < mx1 && trim(cx, mx1, *tp) == 0)
301
263k
                    cx += 8, tp++;
302
88.1k
                if (cx >= mx1)
303
79.9k
                    break;
304
8.15k
                cx += byte_bit_run_length_0[trim(cx, mx1, *tp) ^ 0xff];
305
8.15k
                if (cx >= mx1)
306
0
                    break;
307
8.15k
            }
308
38.0k
            tx1 = cx - cdev->phase.x;
309
            /* Scan a run of 1s. */
310
38.0k
            len = byte_bit_run_length[cx & 7][trim(cx, mx1, *tp)];
311
38.0k
            if (len < 8) {
312
23.2k
                cx += len;
313
23.2k
                if (cx > mx1)
314
0
                    cx = mx1;
315
23.2k
            } else {
316
14.7k
                cx += len - 8;
317
14.7k
                tp++;
318
48.6k
                while (cx < mx1 && trim(cx, mx1, *tp) == 0xff)
319
33.8k
                    cx += 8, tp++;
320
14.7k
                if (cx > mx1)
321
0
                    cx = mx1;
322
14.7k
                else {
323
14.7k
                    cx += byte_bit_run_length_0[trim(cx, mx1, *tp)];
324
14.7k
#undef trim
325
14.7k
                    if (cx > mx1)
326
0
                        cx = mx1;
327
14.7k
                }
328
14.7k
            }
329
38.0k
            tx = cx - cdev->phase.x;
330
38.0k
            if_debug2m('B', cdev->memory, " %d-%d,", tx1, tx);
331
38.0k
            ty = cy - cdev->phase.y;
332
            /* Detect vertical rectangles. */
333
38.0k
            if (prev.p.x == tx1 && prev.q.x == tx && prev.q.y == ty)
334
2.35k
                prev.q.y = ty + 1;
335
35.6k
            else {
336
35.6k
                if (prev.q.y > prev.p.y) {
337
9.18k
                    code = (*process)(pccd, prev.p.x, prev.p.y, prev.q.x, prev.q.y);
338
9.18k
                    if (code < 0)
339
0
                        return code;
340
9.18k
                }
341
35.6k
                prev.p.x = tx1;
342
35.6k
                prev.p.y = ty;
343
35.6k
                prev.q.x = tx;
344
35.6k
                prev.q.y = ty + 1;
345
35.6k
            }
346
38.0k
        }
347
107k
        if_debug0m('B', cdev->memory, "\n");
348
107k
        tile_row += cdev->tiles.raster;
349
107k
    }
350
93.7k
    if (prev.q.y > prev.p.y) {
351
26.4k
        code = (*process)(pccd, prev.p.x, prev.p.y, prev.q.x, prev.q.y);
352
26.4k
        if (code < 0)
353
0
            return code;
354
26.4k
    }
355
93.7k
    return 0;
356
93.7k
}
357
358
/* Copy a color rectangle */
359
static int
360
mask_clip_copy_color(gx_device * dev,
361
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
362
                     int x, int y, int w, int h)
363
0
{
364
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
365
0
    clip_callback_data_t ccdata;
366
367
0
    ccdata.tdev = cdev->target;
368
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
369
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
370
0
    return clip_runs_enumerate(cdev, clip_call_copy_color, &ccdata);
371
0
}
372
373
/* Copy a rectangle with alpha */
374
static int
375
mask_clip_copy_alpha(gx_device * dev,
376
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
377
                int x, int y, int w, int h, gx_color_index color, int depth)
378
0
{
379
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
380
0
    clip_callback_data_t ccdata;
381
382
0
    ccdata.tdev = cdev->target;
383
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
384
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
385
0
    ccdata.color[0] = color, ccdata.depth = depth;
386
0
    return clip_runs_enumerate(cdev, clip_call_copy_alpha, &ccdata);
387
0
}
388
389
static int
390
mask_clip_copy_alpha_hl_color(gx_device * dev,
391
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
392
                int x, int y, int w, int h, const gx_drawing_color *pdcolor,
393
                int depth)
394
0
{
395
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
396
0
    clip_callback_data_t ccdata;
397
398
0
    ccdata.tdev = cdev->target;
399
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
400
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
401
0
    ccdata.pdcolor = pdcolor, ccdata.depth = depth;
402
0
    return clip_runs_enumerate(cdev, clip_call_copy_alpha_hl_color, &ccdata);
403
0
}
404
405
static int
406
mask_clip_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
407
                               int x, int y, int w, int h,
408
                               gx_color_index color0, gx_color_index color1,
409
                               int phase_x, int phase_y)
410
93.7k
{
411
93.7k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
412
93.7k
    clip_callback_data_t ccdata;
413
414
93.7k
    ccdata.tdev = cdev->target;
415
93.7k
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
416
93.7k
    ccdata.tiles = tiles;
417
93.7k
    ccdata.color[0] = color0, ccdata.color[1] = color1;
418
93.7k
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y;
419
93.7k
    return clip_runs_enumerate(cdev, clip_call_strip_tile_rectangle, &ccdata);
420
93.7k
}
421
422
static int
423
mask_clip_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles,
424
                               int x, int y, int w, int h,
425
                               const gx_drawing_color *pdcolor0,
426
                               const gx_drawing_color *pdcolor1,
427
                               int phase_x, int phase_y)
428
0
{
429
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
430
0
    clip_callback_data_t ccdata;
431
432
0
    ccdata.tdev = cdev->target;
433
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
434
0
    ccdata.tiles = tiles;
435
0
    ccdata.pdc[0] = pdcolor0, ccdata.pdc[1] = pdcolor1;
436
0
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y;
437
0
    return clip_runs_enumerate(cdev, clip_call_strip_tile_rect_devn, &ccdata);
438
0
}
439
440
static int
441
mask_clip_strip_copy_rop2(gx_device * dev,
442
               const byte * data, int sourcex, uint raster, gx_bitmap_id id,
443
                         const gx_color_index * scolors,
444
           const gx_strip_bitmap * textures, const gx_color_index * tcolors,
445
                         int x, int y, int w, int h,
446
                       int phase_x, int phase_y, gs_logical_operation_t lop,
447
                       uint planar_height)
448
0
{
449
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
450
0
    clip_callback_data_t ccdata;
451
452
0
    ccdata.tdev = cdev->target;
453
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
454
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
455
0
    ccdata.scolors = scolors, ccdata.textures = textures,
456
0
        ccdata.tcolors = tcolors;
457
0
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y, ccdata.lop = lop;
458
0
    ccdata.plane_height = planar_height;
459
0
    return clip_runs_enumerate(cdev, clip_call_strip_copy_rop2, &ccdata);
460
0
}
461
462
static void
463
mask_clip_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
464
0
{
465
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
466
0
    gx_device *tdev = cdev->target;
467
0
    gs_fixed_rect tbox;
468
469
0
    (*dev_proc(tdev, get_clipping_box)) (tdev, &tbox);
470
0
    pbox->p.x = tbox.p.x - cdev->phase.x;
471
0
    pbox->p.y = tbox.p.y - cdev->phase.y;
472
0
    pbox->q.x = tbox.q.x - cdev->phase.x;
473
0
    pbox->q.y = tbox.q.y - cdev->phase.y;
474
0
}