Coverage Report

Created: 2025-06-24 07:01

/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
321
{
43
321
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
44
321
    set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color);
45
321
    set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb);
46
321
    set_dev_proc(dev, fill_rectangle, mask_clip_fill_rectangle);
47
321
    set_dev_proc(dev, copy_mono, mask_clip_copy_mono);
48
321
    set_dev_proc(dev, copy_color, mask_clip_copy_color);
49
321
    set_dev_proc(dev, get_params, gx_forward_get_params);
50
321
    set_dev_proc(dev, put_params, gx_forward_put_params);
51
321
    set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color);
52
321
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
53
321
    set_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits);
54
321
    set_dev_proc(dev, copy_alpha, mask_clip_copy_alpha);
55
321
    set_dev_proc(dev, strip_tile_rectangle, mask_clip_strip_tile_rectangle);
56
321
    set_dev_proc(dev, get_clipping_box, mask_clip_get_clipping_box);
57
321
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
58
321
    set_dev_proc(dev, composite, gx_no_composite);
59
321
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
60
321
    set_dev_proc(dev, get_color_mapping_procs, gx_forward_get_color_mapping_procs);
61
321
    set_dev_proc(dev, get_color_comp_index, gx_forward_get_color_comp_index);
62
321
    set_dev_proc(dev, encode_color, gx_forward_encode_color);
63
321
    set_dev_proc(dev, decode_color, gx_forward_decode_color);
64
321
    set_dev_proc(dev, fill_rectangle_hl_color, mask_clip_fill_rectangle_hl_color);
65
321
    set_dev_proc(dev, include_color_space, gx_forward_include_color_space);
66
321
    set_dev_proc(dev, fill_linear_color_scanline, gx_forward_fill_linear_color_scanline);
67
321
    set_dev_proc(dev, fill_linear_color_trapezoid, gx_forward_fill_linear_color_trapezoid);
68
321
    set_dev_proc(dev, fill_linear_color_triangle, gx_forward_fill_linear_color_triangle);
69
321
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
70
321
    set_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params);
71
321
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
72
321
    set_dev_proc(dev, dev_spec_op, gx_forward_dev_spec_op);
73
321
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
74
321
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
75
321
    set_dev_proc(dev, strip_copy_rop2, mask_clip_strip_copy_rop2);
76
321
    set_dev_proc(dev, strip_tile_rect_devn, mask_clip_strip_tile_rect_devn);
77
321
    set_dev_proc(dev, copy_alpha_hl_color, mask_clip_copy_alpha_hl_color);
78
321
    set_dev_proc(dev, transform_pixel_region, gx_default_transform_pixel_region);
79
321
    set_dev_proc(dev, fill_stroke_path, gx_forward_fill_stroke_path);
80
321
    set_dev_proc(dev, lock_pattern, gx_forward_lock_pattern);
81
82
    /* Ideally these defaults would be set up automatically for us. */
83
321
    set_dev_proc(dev, open_device, gx_default_open_device);
84
321
    set_dev_proc(dev, sync_output, gx_default_sync_output);
85
321
    set_dev_proc(dev, output_page, gx_default_output_page);
86
321
    set_dev_proc(dev, close_device, gx_default_close_device);
87
321
    set_dev_proc(dev, fill_path, gx_default_fill_path);
88
321
    set_dev_proc(dev, stroke_path, gx_default_stroke_path);
89
321
    set_dev_proc(dev, fill_mask, gx_default_fill_mask);
90
321
    set_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid);
91
321
    set_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram);
92
321
    set_dev_proc(dev, fill_triangle, gx_default_fill_triangle);
93
321
    set_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line);
94
321
    set_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image);
95
321
    set_dev_proc(dev, text_begin, gx_default_text_begin);
96
97
321
 }
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
25.8k
{
113
25.8k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
114
25.8k
    gx_device *tdev = cdev->target;
115
25.8k
    int x, y, w, h;
116
25.8k
    int mx0, mx1, my0, my1;
117
118
25.8k
    x = fixed2int(rect->p.x);
119
25.8k
    y = fixed2int(rect->p.y);
120
25.8k
    w = fixed2int(rect->q.x) - x;
121
25.8k
    h = fixed2int(rect->q.y) - y;
122
123
    /* Clip the rectangle to the region covered by the mask. */
124
25.8k
    mx0 = x + cdev->phase.x;
125
25.8k
    my0 = y + cdev->phase.y;
126
25.8k
    mx1 = mx0 + w;
127
25.8k
    my1 = my0 + h;
128
129
25.8k
    if (mx0 < 0)
130
0
        mx0 = 0;
131
25.8k
    if (my0 < 0)
132
0
        my0 = 0;
133
25.8k
    if (mx1 > cdev->tiles.size.x)
134
0
        mx1 = cdev->tiles.size.x;
135
25.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
25.8k
    return (pdcolor->type->fill_masked)
140
25.8k
            (pdcolor, cdev->tiles.data + my0 * cdev->tiles.raster, mx0,
141
25.8k
             cdev->tiles.raster, cdev->tiles.id, mx0 - cdev->phase.x,
142
25.8k
             my0 - cdev->phase.y, mx1 - mx0, my1 - my0,
143
25.8k
             tdev, lop_default, false);
144
25.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
128k
{
151
128k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
152
128k
    gx_device *tdev = cdev->target;
153
154
    /* Clip the rectangle to the region covered by the mask. */
155
128k
    int mx0 = x + cdev->phase.x, my0 = y + cdev->phase.y;
156
128k
    int mx1 = mx0 + w, my1 = my0 + h;
157
158
128k
    if (mx0 < 0)
159
0
        mx0 = 0;
160
128k
    if (my0 < 0)
161
0
        my0 = 0;
162
128k
    if (mx1 > cdev->tiles.size.x)
163
0
        mx1 = cdev->tiles.size.x;
164
128k
    if (my1 > cdev->tiles.size.y)
165
0
        my1 = cdev->tiles.size.y;
166
128k
    return (*dev_proc(tdev, copy_mono))
167
128k
        (tdev, cdev->tiles.data + my0 * cdev->tiles.raster, mx0,
168
128k
         cdev->tiles.raster, cdev->tiles.id,
169
128k
         mx0 - cdev->phase.x, my0 - cdev->phase.y,
170
128k
         mx1 - mx0, my1 - my0, gx_no_color_index, color);
171
128k
}
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
636k
        const byte *sdata;\
182
636k
        int sx, mx0, my0, mx1, my1
183
#define FIT_MASK_COPY(data, sourcex, raster, vx, vy, vw, vh)\
184
659k
        BEGIN\
185
659k
          sdata = data, sx = sourcex;\
186
659k
          mx0 = vx + cdev->phase.x, my0 = vy + cdev->phase.y;\
187
659k
          mx1 = mx0 + vw, my1 = my0 + vh;\
188
659k
          if ( mx0 < 0 )\
189
659k
            sx -= mx0, mx0 = 0;\
190
659k
          if ( my0 < 0 )\
191
659k
            sdata -= my0 * raster, my0 = 0;\
192
659k
          if ( mx1 > cdev->tiles.size.x )\
193
659k
            mx1 = cdev->tiles.size.x;\
194
659k
          if ( my1 > cdev->tiles.size.y )\
195
659k
            my1 = cdev->tiles.size.y;\
196
659k
        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
22.9k
{
205
22.9k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
206
22.9k
    gx_device *tdev = cdev->target;
207
22.9k
    gx_color_index color, mcolor0, mcolor1;
208
209
22.9k
    DECLARE_MASK_COPY;
210
22.9k
    int cy, ny;
211
22.9k
    int code;
212
213
22.9k
    setup_mask_copy_mono(cdev, color, mcolor0, mcolor1);
214
22.9k
    FIT_MASK_COPY(data, sourcex, raster, x, y, w, h);
215
45.8k
    for (cy = my0; cy < my1; cy += ny) {
216
22.9k
        int ty = cy - cdev->phase.y;
217
22.9k
        int cx, nx;
218
219
22.9k
        ny = my1 - cy;
220
22.9k
        if (ny > cdev->mdev.height)
221
0
            ny = cdev->mdev.height;
222
45.8k
        for (cx = mx0; cx < mx1; cx += nx) {
223
22.9k
            int tx = cx - cdev->phase.x;
224
225
22.9k
            nx = mx1 - cx;  /* also should be min */
226
            /* Copy a tile slice to the memory device buffer. */
227
22.9k
            memcpy(cdev->buffer.bytes,
228
22.9k
                   cdev->tiles.data + cy * cdev->tiles.raster,
229
22.9k
                   (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
22.9k
            (*dev_proc(&cdev->mdev, copy_mono)) ((gx_device *) & cdev->mdev,
234
22.9k
                                     sdata + (ty - y) * raster, sx + tx - x,
235
22.9k
                                                 raster, gx_no_bitmap_id,
236
22.9k
                                           cx, 0, nx, ny, mcolor0, mcolor1);
237
            /* Now copy the color through the double mask. */
238
22.9k
            code = (*dev_proc(tdev, copy_mono)) (cdev->target,
239
22.9k
                                 cdev->buffer.bytes, cx, cdev->tiles.raster,
240
22.9k
                                                 gx_no_bitmap_id,
241
22.9k
                                  tx, ty, nx, ny, gx_no_color_index, color);
242
22.9k
            if (code < 0)
243
0
                return code;
244
22.9k
        }
245
22.9k
    }
246
22.9k
    return 0;
247
22.9k
}
248
249
#ifdef PACIFY_VALGRIND
250
static inline byte trim(int cx, int mx1, byte v)
251
5.12M
{
252
5.12M
    int mask = 8-(mx1-cx); /* mask < 8 */
253
5.12M
    mask = (mask > 0 ? (0xff<<mask) : 0xff)>>(cx & 7);
254
5.12M
    return v & mask;
255
5.12M
}
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
614k
{
270
614k
    DECLARE_MASK_COPY;
271
614k
    int cy;
272
614k
    const byte *tile_row;
273
614k
    gs_int_rect prev;
274
614k
    int code;
275
276
614k
    FIT_MASK_COPY(pccd->data, pccd->sourcex, pccd->raster,
277
614k
                  pccd->x, pccd->y, pccd->w, pccd->h);
278
614k
    tile_row = cdev->tiles.data + my0 * cdev->tiles.raster + (mx0 >> 3);
279
614k
    prev.p.x = 0; /* arbitrary */
280
614k
    prev.q.x = prev.p.x - 1;  /* an impossible rectangle */
281
614k
    prev.p.y = prev.q.y = -1; /* arbitrary */
282
1.31M
    for (cy = my0; cy < my1; cy++) {
283
704k
        int cx = mx0;
284
704k
        const byte *tp = tile_row;
285
286
704k
        if_debug1m('B', cdev->memory, "[B]clip runs y=%d:", cy - cdev->phase.y);
287
935k
        while (cx < mx1) {
288
807k
            int len;
289
807k
            int tx1, tx, ty;
290
291
            /* Skip a run of 0s. */
292
807k
            len = byte_bit_run_length[cx & 7][trim(cx, mx1, *tp) ^ 0xff];
293
807k
            if (len < 8) {
294
134k
                cx += len;
295
134k
                if (cx >= mx1)
296
0
                    break;
297
673k
            } else {
298
673k
                cx += len - 8;
299
673k
                tp++;
300
3.60M
                while (cx < mx1 && trim(cx, mx1, *tp) == 0)
301
2.93M
                    cx += 8, tp++;
302
673k
                if (cx >= mx1)
303
576k
                    break;
304
96.9k
                cx += byte_bit_run_length_0[trim(cx, mx1, *tp) ^ 0xff];
305
96.9k
                if (cx >= mx1)
306
0
                    break;
307
96.9k
            }
308
231k
            tx1 = cx - cdev->phase.x;
309
            /* Scan a run of 1s. */
310
231k
            len = byte_bit_run_length[cx & 7][trim(cx, mx1, *tp)];
311
231k
            if (len < 8) {
312
82.8k
                cx += len;
313
82.8k
                if (cx > mx1)
314
0
                    cx = mx1;
315
148k
            } else {
316
148k
                cx += len - 8;
317
148k
                tp++;
318
818k
                while (cx < mx1 && trim(cx, mx1, *tp) == 0xff)
319
670k
                    cx += 8, tp++;
320
148k
                if (cx > mx1)
321
0
                    cx = mx1;
322
148k
                else {
323
148k
                    cx += byte_bit_run_length_0[trim(cx, mx1, *tp)];
324
148k
#undef trim
325
148k
                    if (cx > mx1)
326
0
                        cx = mx1;
327
148k
                }
328
148k
            }
329
231k
            tx = cx - cdev->phase.x;
330
231k
            if_debug2m('B', cdev->memory, " %d-%d,", tx1, tx);
331
231k
            ty = cy - cdev->phase.y;
332
            /* Detect vertical rectangles. */
333
231k
            if (prev.p.x == tx1 && prev.q.x == tx && prev.q.y == ty)
334
8.74k
                prev.q.y = ty + 1;
335
222k
            else {
336
222k
                if (prev.q.y > prev.p.y) {
337
83.1k
                    code = (*process)(pccd, prev.p.x, prev.p.y, prev.q.x, prev.q.y);
338
83.1k
                    if (code < 0)
339
0
                        return code;
340
83.1k
                }
341
222k
                prev.p.x = tx1;
342
222k
                prev.p.y = ty;
343
222k
                prev.q.x = tx;
344
222k
                prev.q.y = ty + 1;
345
222k
            }
346
231k
        }
347
704k
        if_debug0m('B', cdev->memory, "\n");
348
704k
        tile_row += cdev->tiles.raster;
349
704k
    }
350
614k
    if (prev.q.y > prev.p.y) {
351
139k
        code = (*process)(pccd, prev.p.x, prev.p.y, prev.q.x, prev.q.y);
352
139k
        if (code < 0)
353
0
            return code;
354
139k
    }
355
614k
    return 0;
356
614k
}
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
270k
{
364
270k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
365
270k
    clip_callback_data_t ccdata;
366
367
270k
    ccdata.tdev = cdev->target;
368
270k
    ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster;
369
270k
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
370
270k
    return clip_runs_enumerate(cdev, clip_call_copy_color, &ccdata);
371
270k
}
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
343k
{
411
343k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
412
343k
    clip_callback_data_t ccdata;
413
414
343k
    ccdata.tdev = cdev->target;
415
343k
    ccdata.x = x, ccdata.y = y, ccdata.w = w, ccdata.h = h;
416
343k
    ccdata.tiles = tiles;
417
343k
    ccdata.color[0] = color0, ccdata.color[1] = color1;
418
343k
    ccdata.phase.x = phase_x, ccdata.phase.y = phase_y;
419
343k
    return clip_runs_enumerate(cdev, clip_call_strip_tile_rectangle, &ccdata);
420
343k
}
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
15.1k
{
465
15.1k
    gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev;
466
15.1k
    gx_device *tdev = cdev->target;
467
15.1k
    gs_fixed_rect tbox;
468
469
15.1k
    (*dev_proc(tdev, get_clipping_box)) (tdev, &tbox);
470
15.1k
    pbox->p.x = tbox.p.x - cdev->phase.x;
471
15.1k
    pbox->p.y = tbox.p.y - cdev->phase.y;
472
15.1k
    pbox->q.x = tbox.q.x - cdev->phase.x;
473
15.1k
    pbox->q.y = tbox.q.y - cdev->phase.y;
474
15.1k
}