Coverage Report

Created: 2025-06-10 07:27

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