Coverage Report

Created: 2026-08-08 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gxclipm.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
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
289
{
43
289
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
44
289
    set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color);
45
289
    set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb);
46
289
    set_dev_proc(dev, fill_rectangle, mask_clip_fill_rectangle);
47
289
    set_dev_proc(dev, copy_mono, mask_clip_copy_mono);
48
289
    set_dev_proc(dev, copy_color, mask_clip_copy_color);
49
289
    set_dev_proc(dev, get_params, gx_forward_get_params);
50
289
    set_dev_proc(dev, put_params, gx_forward_put_params);
51
289
    set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color);
52
289
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
53
289
    set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits);
54
289
    set_dev_proc(dev, copy_alpha, mask_clip_copy_alpha);
55
289
    set_dev_proc(dev, strip_tile_rectangle, mask_clip_strip_tile_rectangle);
56
289
    set_dev_proc(dev, get_clipping_box, mask_clip_get_clipping_box);
57
289
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
58
289
    set_dev_proc(dev, composite, gx_no_composite);
59
289
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
60
289
    set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs);
61
289
    set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index);
62
289
    set_dev_proc(dev, encode_color, gx_forward_encode_color);
63
289
    set_dev_proc(dev, decode_color, gx_forward_decode_color);
64
289
    set_dev_proc(dev, fill_rectangle_hl_color, mask_clip_fill_rectangle_hl_color);
65
289
    set_dev_proc(dev, include_color_space, gx_forward_include_color_space);
66
289
    set_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline);
67
289
    set_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid);
68
289
    set_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle);
69
289
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
70
289
    set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params);
71
289
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
72
289
    set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op);
73
289
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
74
289
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
75
289
    set_dev_proc(dev, strip_copy_rop2, mask_clip_strip_copy_rop2);
76
289
    set_dev_proc(dev, strip_tile_rect_devn, mask_clip_strip_tile_rect_devn);
77
289
    set_dev_proc(dev, copy_alpha_hl_color, mask_clip_copy_alpha_hl_color);
78
289
    set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region);
79
289
    set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path);
80
289
    set_dev_proc(dev, lock_pattern, gx_forward_lock_pattern);
81
82
    /* Ideally these defaults would be set up automatically for us. */
83
289
    set_dev_proc(dev, open_device, gx_default_open_device);
84
289
    set_dev_proc(dev, sync_output, gx_default_sync_output);
85
289
    set_dev_proc(dev, output_page, gx_default_output_page);
86
289
    set_dev_proc(dev, close_device, gx_default_close_device);
87
289
    set_dev_proc(dev, fill_path, gx_default_fill_path);
88
289
    set_dev_proc(dev, stroke_path, gx_default_stroke_path);
89
289
    set_dev_proc(dev, fill_mask, gx_default_fill_mask);
90
289
    set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid);
91
289
    set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram);
92
289
    set_dev_proc(dev, fill_triangle, gx_default_fill_triangle);
93
289
    set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line);
94
289
    set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image);
95
289
    set_dev_proc(dev, text_begin, gx_default_text_begin);
96
97
289
 }
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
22.8k
{
113
22.8k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
114
22.8k
    gx_device *tdev = cdev->target;
115
22.8k
    int x, y, w, h;
116
22.8k
    int mx0, mx1, my0, my1;
117
118
22.8k
    x = fixed2int(rect->p.x);
119
22.8k
    y = fixed2int(rect->p.y);
120
22.8k
    w = fixed2int(rect->q.x) - x;
121
22.8k
    h = fixed2int(rect->q.y) - y;
122
123
    /* Clip the rectangle to the region covered by the mask. */
124
22.8k
    mx0 = x + cdev->phase.x;
125
22.8k
    my0 = y + cdev->phase.y;
126
22.8k
    mx1 = mx0 + w;
127
22.8k
    my1 = my0 + h;
128
129
22.8k
    if (mx0 < 0)
130
0
        mx0 = 0;
131
22.8k
    if (my0 < 0)
132
0
        my0 = 0;
133
22.8k
    if (mx1 > cdev->tiles.size.x)
134
0
        mx1 = cdev->tiles.size.x;
135
22.8k
    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
22.8k
    return (pdcolor->type->fill_masked)
140
22.8k
            (pdcolor, cdev->tiles.data + my0 * cdev->tiles.raster, mx0,
141
22.8k
             cdev->tiles.raster, cdev->tiles.id, mx0 - cdev->phase.x,
142
22.8k
             my0 - cdev->phase.y, mx1 - mx0, my1 - my0,
143
22.8k
             tdev, lop_default, false);
144
22.8k
}
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
109k
{
151
109k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
152
109k
    gx_device *tdev = cdev->target;
153
154
    /* Clip the rectangle to the region covered by the mask. */
155
109k
    int mx0 = x + cdev->phase.x, my0 = y + cdev->phase.y;
156
109k
    int mx1 = mx0 + w, my1 = my0 + h;
157
158
109k
    if (mx0 < 0)
159
0
        mx0 = 0;
160
109k
    if (my0 < 0)
161
0
        my0 = 0;
162
109k
    if (mx1 > cdev->tiles.size.x)
163
0
        mx1 = cdev->tiles.size.x;
164
109k
    if (my1 > cdev->tiles.size.y)
165
0
        my1 = cdev->tiles.size.y;
166
109k
    return (*dev_proc(tdev, copy_mono))
167
109k
        (tdev, cdev->tiles.data + my0 * cdev->tiles.raster, mx0,
168
109k
         cdev->tiles.raster, cdev->tiles.id,
169
109k
         mx0 - cdev->phase.x, my0 - cdev->phase.y,
170
109k
         mx1 - mx0, my1 - my0, gx_no_color_index, color);
171
109k
}
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
550k
        const byte *sdata;\
182
550k
        int sx, mx0, my0, mx1, my1
183
#define FIT_MASK_COPY(data, sourcex, raster, vx, vy, vw, vh)\
184
570k
        BEGIN\
185
570k
          sdata = data, sx = sourcex;\
186
570k
          mx0 = vx + cdev->phase.x, my0 = vy + cdev->phase.y;\
187
570k
          mx1 = mx0 + vw, my1 = my0 + vh;\
188
570k
          if ( mx0 < 0 )\
189
570k
            sx -= mx0, mx0 = 0;\
190
570k
          if ( my0 < 0 )\
191
570k
            sdata -= my0 * raster, my0 = 0;\
192
570k
          if ( mx1 > cdev->tiles.size.x )\
193
570k
            mx1 = cdev->tiles.size.x;\
194
570k
          if ( my1 > cdev->tiles.size.y )\
195
570k
            my1 = cdev->tiles.size.y;\
196
570k
        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
20.0k
{
205
20.0k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
206
20.0k
    gx_device *tdev = cdev->target;
207
20.0k
    gx_color_index color, mcolor0, mcolor1;
208
209
20.0k
    DECLARE_MASK_COPY;
210
20.0k
    int cy, ny;
211
20.0k
    int code;
212
213
20.0k
    setup_mask_copy_mono(cdev, color, mcolor0, mcolor1);
214
20.0k
    FIT_MASK_COPY(data, sourcex, raster, x, y, w, h);
215
40.0k
    for (cy = my0; cy < my1; cy += ny) {
216
20.0k
        int ty = cy - cdev->phase.y;
217
20.0k
        int cx, nx;
218
219
20.0k
        ny = my1 - cy;
220
20.0k
        if (ny > cdev->mdev.height)
221
0
            ny = cdev->mdev.height;
222
40.0k
        for (cx = mx0; cx < mx1; cx += nx) {
223
20.0k
            int tx = cx - cdev->phase.x;
224
225
20.0k
            nx = mx1 - cx;  /* also should be min */
226
            /* Copy a tile slice to the memory device buffer. */
227
20.0k
            memcpy(cdev->buffer.bytes,
228
20.0k
                   cdev->tiles.data + cy * cdev->tiles.raster,
229
20.0k
                   (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
20.0k
            (*dev_proc(&cdev->mdev, copy_mono)) ((gx_device *) & cdev->mdev,
234
20.0k
                                     sdata + (ty - y) * raster, sx + tx - x,
235
20.0k
                                                 raster, gx_no_bitmap_id,
236
20.0k
                                           cx, 0, nx, ny, mcolor0, mcolor1);
237
            /* Now copy the color through the double mask. */
238
20.0k
            code = (*dev_proc(tdev, copy_mono)) (cdev->target,
239
20.0k
                                 cdev->buffer.bytes, cx, cdev->tiles.raster,
240
20.0k
                                                 gx_no_bitmap_id,
241
20.0k
                                  tx, ty, nx, ny, gx_no_color_index, color);
242
20.0k
            if (code < 0)
243
0
                return code;
244
20.0k
        }
245
20.0k
    }
246
20.0k
    return 0;
247
20.0k
}
248
249
#ifdef PACIFY_VALGRIND
250
static inline byte trim(int cx, int mx1, byte v)
251
4.78M
{
252
4.78M
    int mask = 8-(mx1-cx); /* mask < 8 */
253
4.78M
    mask = (mask > 0 ? (0xff<<mask) : 0xff)>>(cx & 7);
254
4.78M
    return v & mask;
255
4.78M
}
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
530k
{
270
530k
    DECLARE_MASK_COPY;
271
530k
    int cy;
272
530k
    const byte *tile_row;
273
530k
    gs_int_rect prev;
274
530k
    int code;
275
530k
    (void)sdata; /* Declared in DECLARE_MASK_COPY but not used here */
276
277
530k
    FIT_MASK_COPY(pccd->data, pccd->sourcex, pccd->raster,
278
530k
                  pccd->x, pccd->y, pccd->w, pccd->h);
279
530k
    tile_row = cdev->tiles.data + my0 * cdev->tiles.raster + (mx0 >> 3);
280
530k
    prev.p.x = 0; /* arbitrary */
281
530k
    prev.q.x = prev.p.x - 1;  /* an impossible rectangle */
282
530k
    prev.p.y = prev.q.y = -1; /* arbitrary */
283
1.13M
    for (cy = my0; cy < my1; cy++) {
284
608k
        int cx = mx0;
285
608k
        const byte *tp = tile_row;
286
287
608k
        if_debug1m('B', cdev->memory, "[B]clip runs y=%d:", cy - cdev->phase.y);
288
826k
        while (cx < mx1) {
289
706k
            int len;
290
706k
            int tx1, tx, ty;
291
292
            /* Skip a run of 0s. */
293
706k
            len = byte_bit_run_length[cx & 7][trim(cx, mx1, *tp) ^ 0xff];
294
706k
            if (len < 8) {
295
125k
                cx += len;
296
125k
                if (cx >= mx1)
297
0
                    break;
298
580k
            } else {
299
580k
                cx += len - 8;
300
580k
                tp++;
301
3.37M
                while (cx < mx1 && trim(cx, mx1, *tp) == 0)
302
2.79M
                    cx += 8, tp++;
303
580k
                if (cx >= mx1)
304
488k
                    break;
305
91.9k
                cx += byte_bit_run_length_0[trim(cx, mx1, *tp) ^ 0xff];
306
91.9k
                if (cx >= mx1)
307
0
                    break;
308
91.9k
            }
309
217k
            tx1 = cx - cdev->phase.x;
310
            /* Scan a run of 1s. */
311
217k
            len = byte_bit_run_length[cx & 7][trim(cx, mx1, *tp)];
312
217k
            if (len < 8) {
313
77.8k
                cx += len;
314
77.8k
                if (cx > mx1)
315
0
                    cx = mx1;
316
139k
            } else {
317
139k
                cx += len - 8;
318
139k
                tp++;
319
761k
                while (cx < mx1 && trim(cx, mx1, *tp) == 0xff)
320
621k
                    cx += 8, tp++;
321
139k
                if (cx > mx1)
322
0
                    cx = mx1;
323
139k
                else {
324
139k
                    cx += byte_bit_run_length_0[trim(cx, mx1, *tp)];
325
139k
#undef trim
326
139k
                    if (cx > mx1)
327
0
                        cx = mx1;
328
139k
                }
329
139k
            }
330
217k
            tx = cx - cdev->phase.x;
331
217k
            if_debug2m('B', cdev->memory, " %d-%d,", tx1, tx);
332
217k
            ty = cy - cdev->phase.y;
333
            /* Detect vertical rectangles. */
334
217k
            if (prev.p.x == tx1 && prev.q.x == tx && prev.q.y == ty)
335
7.76k
                prev.q.y = ty + 1;
336
210k
            else {
337
210k
                if (prev.q.y > prev.p.y) {
338
79.6k
                    code = (*process)(pccd, prev.p.x, prev.p.y, prev.q.x, prev.q.y);
339
79.6k
                    if (code < 0)
340
0
                        return code;
341
79.6k
                }
342
210k
                prev.p.x = tx1;
343
210k
                prev.p.y = ty;
344
210k
                prev.q.x = tx;
345
210k
                prev.q.y = ty + 1;
346
210k
            }
347
217k
        }
348
608k
        if_debug0m('B', cdev->memory, "\n");
349
608k
        tile_row += cdev->tiles.raster;
350
608k
    }
351
530k
    if (prev.q.y > prev.p.y) {
352
130k
        code = (*process)(pccd, prev.p.x, prev.p.y, prev.q.x, prev.q.y);
353
130k
        if (code < 0)
354
0
            return code;
355
130k
    }
356
530k
    return 0;
357
530k
}
358
359
/* Copy a color rectangle */
360
static int
361
mask_clip_copy_color(gx_device * dev,
362
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
363
                     int x, int y, int w, int h)
364
188k
{
365
188k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
366
188k
    clip_callback_data_t ccdata;
367
368
188k
    ccdata.tdev = cdev->target;
369
188k
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
370
188k
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
371
188k
    return clip_runs_enumerate(cdev, clip_call_copy_color, &ccdata);
372
188k
}
373
374
/* Copy a rectangle with alpha */
375
static int
376
mask_clip_copy_alpha(gx_device * dev,
377
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
378
                int x, int y, int w, int h, gx_color_index color, int depth)
379
0
{
380
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
381
0
    clip_callback_data_t ccdata;
382
383
0
    ccdata.tdev = cdev->target;
384
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
385
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
386
0
    ccdata.color[0] = color, ccdata.depth = depth;
387
0
    return clip_runs_enumerate(cdev, clip_call_copy_alpha, &ccdata);
388
0
}
389
390
static int
391
mask_clip_copy_alpha_hl_color(gx_device * dev,
392
                const byte * data, int sourcex, int raster, gx_bitmap_id id,
393
                int x, int y, int w, int h, const gx_drawing_color *pdcolor,
394
                int depth)
395
0
{
396
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
397
0
    clip_callback_data_t ccdata;
398
399
0
    ccdata.tdev = cdev->target;
400
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
401
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
402
0
    ccdata.pdcolor = pdcolor, ccdata.depth = depth;
403
0
    return clip_runs_enumerate(cdev, clip_call_copy_alpha_hl_color, &ccdata);
404
0
}
405
406
static int
407
mask_clip_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles,
408
                               int x, int y, int w, int h,
409
                               gx_color_index color0, gx_color_index color1,
410
                               int phase_x, int phase_y)
411
341k
{
412
341k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
413
341k
    clip_callback_data_t ccdata;
414
415
341k
    ccdata.tdev = cdev->target;
416
341k
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
417
341k
    ccdata.tiles = tiles;
418
341k
    ccdata.color[0] = color0, ccdata.color[1] = color1;
419
341k
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y;
420
341k
    return clip_runs_enumerate(cdev, clip_call_strip_tile_rectangle, &ccdata);
421
341k
}
422
423
static int
424
mask_clip_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tiles,
425
                               int x, int y, int w, int h,
426
                               const gx_drawing_color *pdcolor0,
427
                               const gx_drawing_color *pdcolor1,
428
                               int phase_x, int phase_y)
429
0
{
430
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
431
0
    clip_callback_data_t ccdata;
432
433
0
    ccdata.tdev = cdev->target;
434
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
435
0
    ccdata.tiles = tiles;
436
0
    ccdata.pdc[0] = pdcolor0, ccdata.pdc[1] = pdcolor1;
437
0
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y;
438
0
    return clip_runs_enumerate(cdev, clip_call_strip_tile_rect_devn, &ccdata);
439
0
}
440
441
static int
442
mask_clip_strip_copy_rop2(gx_device * dev,
443
               const byte * data, int sourcex, uint raster, gx_bitmap_id id,
444
                         const gx_color_index * scolors,
445
           const gx_strip_bitmap * textures, const gx_color_index * tcolors,
446
                         int x, int y, int w, int h,
447
                       int phase_x, int phase_y, gs_logical_operation_t lop,
448
                       uint planar_height)
449
0
{
450
0
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
451
0
    clip_callback_data_t ccdata;
452
453
0
    ccdata.tdev = cdev->target;
454
0
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
455
0
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
456
0
    ccdata.scolors = scolors, ccdata.textures = textures,
457
0
        ccdata.tcolors = tcolors;
458
0
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y, ccdata.lop = lop;
459
0
    ccdata.plane_height = planar_height;
460
0
    return clip_runs_enumerate(cdev, clip_call_strip_copy_rop2, &ccdata);
461
0
}
462
463
static void
464
mask_clip_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox)
465
11.2k
{
466
11.2k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
467
11.2k
    gx_device *tdev = cdev->target;
468
11.2k
    gs_fixed_rect tbox;
469
470
11.2k
    (*dev_proc(tdev, get_clipping_box)) (tdev, &tbox);
471
11.2k
    pbox->p.x = tbox.p.x - cdev->phase.x;
472
11.2k
    pbox->p.y = tbox.p.y - cdev->phase.y;
473
11.2k
    pbox->q.x = tbox.q.x - cdev->phase.x;
474
11.2k
    pbox->q.y = tbox.q.y - cdev->phase.y;
475
11.2k
}