Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gspaint.c
Line
Count
Source
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
/* Painting procedures for Ghostscript library */
18
#include "math_.h"    /* for fabs */
19
#include "gx.h"
20
#include "gpcheck.h"
21
#include "gserrors.h"
22
#include "gsropt.h"   /* for gxpaint.h */
23
#include "gxfixed.h"
24
#include "gxmatrix.h"   /* for gs_gstate */
25
#include "gspaint.h"
26
#include "gspath.h"
27
#include "gzpath.h"
28
#include "gxpaint.h"
29
#include "gxpcolor.h"   /* for do_fill_stroke */
30
#include "gzstate.h"
31
#include "gxdevice.h"
32
#include "gxdevmem.h"
33
#include "gzcpath.h"
34
#include "gxhldevc.h"
35
#include "gsutil.h"
36
#include "gxscanc.h"
37
#include "gxdevsop.h"
38
#include "gsicc_cms.h"
39
#include "gdevepo.h"
40
#include "assert_.h"
41
42
/* Define the nominal size for alpha buffers. */
43
#define abuf_nominal_SMALL 500
44
0
#define abuf_nominal_LARGE 2000
45
#if ARCH_SMALL_MEMORY
46
#  define abuf_nominal abuf_nominal_SMALL
47
#else
48
#ifdef DEBUG
49
#  define abuf_nominal\
50
     (gs_debug_c('.') ? abuf_nominal_SMALL : abuf_nominal_LARGE)
51
#else
52
0
#  define abuf_nominal abuf_nominal_LARGE
53
#endif
54
#endif
55
56
/* Erase the page */
57
int
58
gs_erasepage(gs_gstate * pgs)
59
1.55k
{
60
    /*
61
     * We can't just fill with device white; we must take the
62
     * transfer function into account.
63
     */
64
1.55k
    int code;
65
66
1.55k
    if ((code = gs_gsave(pgs)) < 0)
67
0
        return code;
68
1.55k
    if ((code = gs_setgray(pgs, 1.0)) >= 0) {
69
        /* Fill the page directly, ignoring clipping. */
70
1.55k
        code = gs_fillpage(pgs);
71
1.55k
    }
72
1.55k
    gs_grestore(pgs);
73
1.55k
    return code;
74
1.55k
}
75
76
/* Fill the page with the current color. */
77
int
78
gs_fillpage(gs_gstate * pgs)
79
1.33M
{
80
1.33M
    gx_device *dev = gs_currentdevice(pgs);
81
1.33M
    int code;
82
83
    /*
84
     * No need to check for returning error code,
85
     * existing device will continue to operate as before.
86
     */
87
1.33M
    epo_check_and_install(dev);
88
89
    /* Deliberately use the terminal device here */
90
1.33M
    if (dev_proc(dev, get_color_mapping_procs) ==  gx_error_get_color_mapping_procs) {
91
0
        emprintf1(dev->memory,
92
0
                  "\n   *** Error: No get_color_mapping_procs for device: %s\n",
93
0
                  dev->dname);
94
0
        return_error(gs_error_Fatal);
95
0
    }
96
    /* Processing a fill object operation, but this counts as "UNTOUCHED" */
97
1.33M
    gx_unset_dev_color(pgs);    /* force update so we pick up the new tag */
98
1.33M
    gx_unset_alt_dev_color(pgs);
99
1.33M
    dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_UNTOUCHED_TAG);
100
101
1.33M
    code = gx_set_dev_color(pgs);
102
1.33M
    if (code != 0)
103
0
        return code;
104
105
1.33M
    code = (*dev_proc(dev, fillpage))(dev, pgs, gs_currentdevicecolor_inline(pgs));
106
1.33M
    if (code < 0)
107
0
        return code;
108
109
    /* If GrayDetection is set, make sure monitoring is enabled. */
110
1.33M
    if (dev->icc_struct != NULL &&
111
1.33M
            dev->icc_struct->graydetection && !dev->icc_struct->pageneutralcolor) {
112
0
        dev->icc_struct->pageneutralcolor = true; /* start detecting again */
113
0
        code = gsicc_mcm_begin_monitor(pgs->icc_link_cache, dev);
114
0
    }
115
1.33M
    if (code < 0)
116
0
        return code;
117
1.33M
    return (*dev_proc(dev, sync_output)) (dev);
118
1.33M
}
119
/*
120
 * Set up an alpha buffer for a stroke or fill operation.  Return 0
121
 * if no buffer could be allocated, 1 if a buffer was installed,
122
 * or the usual negative error code.
123
 *
124
 * The fill/stroke code sets up a clipping device if needed; however,
125
 * since we scale up all the path coordinates, we either need to scale up
126
 * the clipping region, or do clipping after, rather than before,
127
 * alpha buffering.  Either of these is a little inconvenient, but
128
 * the former is less inconvenient.
129
 */
130
static int
131
scale_paths(gs_gstate * pgs, int log2_scale_x, int log2_scale_y, bool do_path)
132
0
{
133
    /*
134
     * Because of clip and clippath, any of path, clip_path, and view_clip
135
     * may be aliases for each other.  The only reliable way to detect
136
     * this is by comparing the segments pointers.  Note that we must
137
     * scale the non-segment parts of the paths even if the segments are
138
     * aliased.
139
     */
140
0
    const gx_path_segments *seg_clip =
141
0
        (pgs->clip_path->path_valid ? pgs->clip_path->path.segments : 0);
142
0
    const gx_clip_rect_list *list_clip = pgs->clip_path->rect_list;
143
0
    const gx_path_segments *seg_view_clip;
144
0
    const gx_clip_rect_list *list_view_clip;
145
0
    const gx_path_segments *seg_effective_clip =
146
0
        (pgs->effective_clip_path->path_valid ?
147
0
         pgs->effective_clip_path->path.segments : 0);
148
0
    const gx_clip_rect_list *list_effective_clip =
149
0
        pgs->effective_clip_path->rect_list;
150
151
0
    gx_cpath_scale_exp2_shared(pgs->clip_path, log2_scale_x, log2_scale_y,
152
0
                               false, false);
153
0
    if (pgs->view_clip != 0 && pgs->view_clip != pgs->clip_path) {
154
0
        seg_view_clip =
155
0
            (pgs->view_clip->path_valid ? pgs->view_clip->path.segments : 0);
156
0
        list_view_clip = pgs->view_clip->rect_list;
157
0
        gx_cpath_scale_exp2_shared(pgs->view_clip, log2_scale_x, log2_scale_y,
158
0
                                   list_view_clip == list_clip,
159
0
                                   seg_view_clip && seg_view_clip == seg_clip);
160
0
    } else
161
0
        seg_view_clip = 0, list_view_clip = 0;
162
0
    if (pgs->effective_clip_path != pgs->clip_path &&
163
0
        pgs->effective_clip_path != pgs->view_clip
164
0
        )
165
0
        gx_cpath_scale_exp2_shared(pgs->effective_clip_path, log2_scale_x,
166
0
                                   log2_scale_y,
167
0
                                   list_effective_clip == list_clip ||
168
0
                                   list_effective_clip == list_view_clip,
169
0
                                   seg_effective_clip &&
170
0
                                   (seg_effective_clip == seg_clip ||
171
0
                                    seg_effective_clip == seg_view_clip));
172
0
    if (do_path) {
173
0
        const gx_path_segments *seg_path = pgs->path->segments;
174
175
0
        gx_path_scale_exp2_shared(pgs->path, log2_scale_x, log2_scale_y,
176
0
                                  seg_path == seg_clip ||
177
0
                                  seg_path == seg_view_clip ||
178
0
                                  seg_path == seg_effective_clip);
179
0
    }
180
0
    return 0;
181
0
}
182
static void
183
scale_dash_pattern(gs_gstate * pgs, double scale)
184
0
{
185
0
    int i;
186
187
0
    for (i = 0; i < pgs->line_params.dash.pattern_size; ++i)
188
0
        pgs->line_params.dash.pattern[i] *= scale;
189
0
    pgs->line_params.dash.offset *= scale;
190
0
    pgs->line_params.dash.pattern_length *= scale;
191
0
    pgs->line_params.dash.init_dist_left *= scale;
192
0
    if (pgs->line_params.dot_length_absolute)
193
0
        pgs->line_params.dot_length *= scale;
194
0
}
195
196
/*
197
 Returns 0 for OK.
198
 Returns 1 for "OK, buffer needs releasing"
199
 Returns 2 for "Empty region"
200
 Returns -ve for error
201
 */
202
static int
203
alpha_buffer_init(gs_gstate * pgs, fixed extra_x, fixed extra_y, int alpha_bits,
204
                  bool devn)
205
0
{
206
0
    gx_device *dev = gs_currentdevice_inline(pgs);
207
0
    int log2_alpha_bits = ilog2(alpha_bits);
208
0
    gs_fixed_rect bbox;
209
0
    gs_int_rect ibox;
210
0
    uint width, raster, band_space;
211
0
    uint height, height2;
212
0
    gs_log2_scale_point log2_scale;
213
0
    gs_memory_t *mem;
214
0
    gx_device_memory *mdev;
215
216
0
    log2_scale.x = log2_scale.y = log2_alpha_bits;
217
0
    gx_path_bbox(pgs->path, &bbox);
218
0
    ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1;
219
0
    ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1;
220
0
    ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1;
221
0
    ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1;
222
0
    (void)dev_proc(dev, dev_spec_op)(dev, gxdso_restrict_bbox, &ibox, sizeof(ibox));
223
0
    if ((ibox.q.y <= ibox.p.y) || (ibox.q.x <= ibox.p.x))
224
0
        return 2;
225
0
    width = (ibox.q.x - ibox.p.x) << log2_scale.x;
226
0
    raster = bitmap_raster(width);
227
0
    band_space = raster << log2_scale.y;
228
0
    height2 = (ibox.q.y - ibox.p.y);
229
0
    height = (abuf_nominal / band_space);
230
0
    if (height == 0)
231
0
        height = 1;
232
0
    if (height > height2)
233
0
        height = height2;
234
0
    height <<= log2_scale.y;
235
    /* We may have to update the marking parameters if we have a pdf14 device
236
       as our target.  Need to do while dev is still active in pgs. Do this
237
       before allocating the device to simplify cleanup. */
238
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) {
239
0
        int code = gs_update_trans_marking_params(pgs);
240
0
        if (code < 0)
241
0
            return code;
242
0
    }
243
0
    mem = pgs->memory;
244
0
    mdev = gs_alloc_struct_immovable(mem, gx_device_memory, &st_device_memory,
245
0
                           "alpha_buffer_init");
246
0
    if (mdev == 0)
247
0
        return 0;   /* if no room, don't buffer */
248
0
    gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale,
249
0
                            alpha_bits, ibox.p.x << log2_scale.x, devn);
250
0
    mdev->width = width;
251
0
    mdev->height = height;
252
0
    mdev->bitmap_memory = mem;
253
    /* Set the horrible hacky flag that tells people that the width/height here
254
     * have been set for *our* convenience, rather than accurately depicting the
255
     * size of the device for callers. */
256
0
    mdev->non_strict_bounds = 1;
257
0
    if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) {
258
        /* No room for bits, punt. */
259
0
        gs_free_object(mem, mdev, "alpha_buffer_init");
260
0
        return 0;
261
0
    }
262
0
    gx_set_device_only(pgs, (gx_device *) mdev);
263
0
    scale_paths(pgs, log2_scale.x, log2_scale.y, true);
264
0
    return 1;
265
0
}
266
267
/* Release an alpha buffer. */
268
static int
269
alpha_buffer_release(gs_gstate * pgs, bool newpath)
270
0
{
271
0
    gx_device_memory *mdev =
272
0
        (gx_device_memory *) gs_currentdevice_inline(pgs);
273
0
    int code = (*dev_proc(mdev, close_device)) ((gx_device *) mdev);
274
275
0
    if (code >= 0)
276
0
        scale_paths(pgs, -mdev->log2_scale.x, -mdev->log2_scale.y,
277
0
                !(newpath && !gx_path_is_shared(pgs->path)));
278
    /* Reference counting will free mdev. */
279
0
    gx_set_device_only(pgs, mdev->target);
280
0
    return code;
281
0
}
282
283
/* Setup for black vector handling */
284
static inline bool black_vectors(gs_gstate *pgs, gx_device *dev)
285
11.9M
{
286
11.9M
    if (dev->icc_struct != NULL && dev->icc_struct->blackvector &&
287
0
        pgs->black_textvec_state == NULL) {
288
0
        return gsicc_setup_blacktextvec(pgs, dev, false);
289
0
    }
290
11.9M
    return false;
291
11.9M
}
292
293
static int do_fill(gs_gstate *pgs, int rule)
294
15.8M
{
295
15.8M
    int code, abits, acode, rcode = 0;
296
15.8M
    bool devn;
297
15.8M
    bool black_vector = false;
298
15.8M
    bool in_smask =
299
15.8M
        (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0;
300
301
    /* We need to distinguish text from vectors to set the object tag.
302
303
       To make that determination, we check for the show graphics state being stored
304
       in the current graphics state. This works even in the case of a glyph from a
305
       Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in
306
       the BuildGlyph/BuildChar procedure. Also, it works in the case of operating
307
       without a glyph cache or bypassing the cache because the glyph is too large or
308
       the cache being already full.
309
310
       Note that it doesn't work for a construction like:
311
       "(xyz) true charpath fill/stroke"
312
       where the show machinations have completed before we get to the fill operation.
313
       This has implications for how we handle PDF text rendering modes 1 and 2. To
314
       handle that, we'll have to add a flag to the path structure, or to the path
315
       segment structure (depending on how fine grained we require it to be).
316
     */
317
15.8M
    if (pgs->show_gstate == NULL && !in_smask) {
318
6.45M
        ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */
319
6.45M
        black_vector = black_vectors(pgs, pgs->device); /* Set vector fill to black */
320
6.45M
    } else
321
9.36M
        ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
322
323
15.8M
    code = gx_set_dev_color(pgs);
324
15.8M
    if (code != 0)
325
130k
        goto out;
326
15.6M
    code = gs_gstate_color_load(pgs);
327
15.6M
    if (code < 0)
328
0
        goto out;
329
330
15.6M
    if (pgs->overprint || (!pgs->overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
331
15.3M
        gxdso_overprint_active, NULL, 0))) {
332
320k
        gs_overprint_params_t op_params = { 0 };
333
334
320k
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
335
320k
            "[overprint] Fill Overprint\n");
336
320k
        code = gs_do_set_overprint(pgs);
337
320k
        if (code < 0)
338
0
            goto out;
339
340
320k
        op_params.op_state = OP_STATE_FILL;
341
320k
        gs_gstate_update_overprint(pgs, &op_params);
342
320k
    }
343
344
15.6M
    abits = 0;
345
15.6M
    {
346
15.6M
        gx_device_color *col = gs_currentdevicecolor_inline(pgs);
347
15.6M
        devn = color_is_devn(col);
348
15.6M
        if (color_is_pure(col) || devn)
349
13.8M
            abits = alpha_buffer_bits(pgs);
350
15.6M
    }
351
15.6M
    if (abits > 1) {
352
0
        acode = alpha_buffer_init(pgs, pgs->fill_adjust.x,
353
0
                                  pgs->fill_adjust.y, abits, devn);
354
0
        if (acode == 2) { /* Special case for no fill required */
355
0
            code = 0;
356
0
            goto out;
357
0
        }
358
0
        if (acode < 0) {
359
0
            code = acode;
360
0
            goto out;
361
0
        }
362
0
    } else
363
15.6M
        acode = 0;
364
15.6M
    code = gx_fill_path(pgs->path, gs_currentdevicecolor_inline(pgs), pgs, rule,
365
15.6M
                        pgs->fill_adjust.x, pgs->fill_adjust.y);
366
15.6M
    if (acode > 0)
367
0
        rcode = alpha_buffer_release(pgs, code >= 0);
368
15.6M
    if (code >= 0 && rcode < 0)
369
0
        code = rcode;
370
371
15.8M
out:
372
15.8M
    if (black_vector) {
373
        /* Restore color */
374
0
        gsicc_restore_blacktextvec(pgs, false);
375
0
    }
376
377
15.8M
    return code;
378
15.6M
}
379
380
/* Fill the current path using a specified rule. */
381
static int
382
fill_with_rule(gs_gstate * pgs, int rule)
383
15.8M
{
384
15.8M
    int code;
385
386
    /* If we're inside a charpath, just merge the current path */
387
    /* into the parent's path. */
388
15.8M
    if (pgs->in_charpath)
389
0
        code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
390
0
                                     pgs->in_charpath);
391
            /* If we're rendering a glyph cached, the show machinery decides
392
             * whether to actually image it on the output or not, but uncached
393
             * will render directly to the output, so for text rendering
394
             * mode 3, we have to short circuit it here, but keep the
395
             * current point
396
             */
397
15.8M
    else if (gs_is_null_device(pgs->device)
398
15.8M
            || (pgs->show_gstate && pgs->text_rendering_mode == 3
399
74
            && pgs->in_cachedevice == CACHE_DEVICE_NOT_CACHING)) {
400
        /* Handle separately to prevent gs_gstate_color_load - bug 688308. */
401
74
        gs_newpath(pgs);
402
74
        code = 0;
403
15.8M
    } else {
404
15.8M
        code = do_fill(pgs, rule);
405
15.8M
        if (code >= 0)
406
15.6M
            code = gs_newpath(pgs);
407
15.8M
    }
408
15.8M
    return code;
409
15.8M
}
410
/* Fill using the winding number rule */
411
int
412
gs_fill(gs_gstate * pgs)
413
15.2M
{
414
15.2M
    pgs->device->sgr.stroke_stored = false;
415
15.2M
    return fill_with_rule(pgs, gx_rule_winding_number);
416
15.2M
}
417
/* Fill using the even/odd rule */
418
int
419
gs_eofill(gs_gstate * pgs)
420
554k
{
421
554k
    pgs->device->sgr.stroke_stored = false;
422
554k
    return fill_with_rule(pgs, gx_rule_even_odd);
423
554k
}
424
425
static int
426
do_stroke(gs_gstate * pgs)
427
5.38M
{
428
5.38M
    int code, abits, acode, rcode = 0;
429
5.38M
    bool devn;
430
5.38M
    bool is_fill_correct = true;
431
5.38M
    bool black_vector = false;
432
5.38M
    bool in_smask =
433
5.38M
        (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0;
434
435
436
    /* We need to distinguish text from vectors to set the object tag.
437
438
       To make that determination, we check for the show graphics state being stored
439
       in the current graphics state. This works even in the case of a glyph from a
440
       Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in
441
       the BuildGlyph/BuildChar procedure. Also, it works in the case of operating
442
       without a glyph cache or bypassing the cache because the glyph is too large or
443
       the cache being already full.
444
445
       Note that it doesn't work for a construction like:
446
       "(xyz) true charpath fill/stroke"
447
       where the show machinations have completed before we get to the fill operation.
448
       This has implications for how we handle PDF text rendering modes 1 and 2. To
449
       handle that, we'll have to add a flag to the path structure, or to the path
450
       segment structure (depending on how fine grained we require it to be).
451
     */
452
5.38M
    if (pgs->show_gstate == NULL && !in_smask) {
453
5.37M
        ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */
454
5.37M
        black_vector = black_vectors(pgs, pgs->device);
455
5.37M
    } else
456
5.51k
        ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
457
458
5.38M
    code = gx_set_dev_color(pgs);
459
5.38M
    if (code != 0)
460
7.96k
        goto out;
461
5.37M
    code = gs_gstate_color_load(pgs);
462
5.37M
    if (code < 0)
463
0
        goto out;
464
465
466
5.37M
    if (pgs->stroke_overprint || (!pgs->stroke_overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
467
5.08M
        gxdso_overprint_active, NULL, 0))) {
468
284k
        gs_overprint_params_t op_params = { 0 };
469
470
        /* PS2 does not have the concept of fill and stroke colors. Here we need to possibly correct
471
           for that in the graphic state during this operation */
472
284k
        if (pgs->is_fill_color) {
473
0
            is_fill_correct = false;
474
0
            pgs->is_fill_color = false;
475
0
        }
476
477
478
284k
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
479
284k
            "[overprint] Stroke Overprint\n");
480
284k
        code = gs_do_set_overprint(pgs);
481
284k
        if (code < 0) {
482
0
            if (!is_fill_correct) {
483
0
                pgs->is_fill_color = true;
484
0
            }
485
0
            goto out;
486
0
        }
487
488
284k
        op_params.op_state = OP_STATE_STROKE;
489
284k
        gs_gstate_update_overprint(pgs, &op_params);
490
284k
    }
491
492
5.37M
    abits = 0;
493
5.37M
    {
494
5.37M
        gx_device_color *col = gs_currentdevicecolor_inline(pgs);
495
5.37M
        devn = color_is_devn(col);
496
5.37M
        if (color_is_pure(col) || devn)
497
4.96M
            abits = alpha_buffer_bits(pgs);
498
5.37M
    }
499
5.37M
    if (abits > 1) {
500
        /*
501
         * Expand the bounding box by the line width.
502
         * This is expensive to compute, so we only do it
503
         * if we know we're going to buffer.
504
         */
505
0
        float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
506
0
        float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
507
0
        float scale = (float)(1 << (abits / 2));
508
0
        float orig_width = gs_currentlinewidth(pgs);
509
0
        float new_width = orig_width * scale;
510
0
        fixed extra_adjust =
511
0
                float2fixed(max(xxyy, xyyx) * new_width / 2);
512
0
        float orig_flatness = gs_currentflat(pgs);
513
0
        gx_path spath;
514
515
        /* Scale up the line width, dash pattern, and flatness. */
516
0
        if (extra_adjust < fixed_1)
517
0
            extra_adjust = fixed_1;
518
0
        acode = alpha_buffer_init(pgs,
519
0
                                  pgs->fill_adjust.x + extra_adjust,
520
0
                                  pgs->fill_adjust.y + extra_adjust,
521
0
                                  abits, devn);
522
0
        if (acode == 2) {            /* Special code meaning no fill required */
523
0
            if (!is_fill_correct) {
524
0
                pgs->is_fill_color = true;
525
0
            }
526
0
            code = 0;
527
0
            goto out;
528
0
        }
529
0
        if (acode < 0) {
530
0
            if (!is_fill_correct) {
531
0
                pgs->is_fill_color = true;
532
0
            }
533
0
            code = acode;
534
0
            goto out;
535
0
        }
536
0
        gs_setlinewidth(pgs, new_width);
537
0
        scale_dash_pattern(pgs, scale);
538
0
        gs_setflat(pgs, (double)(orig_flatness * scale));
539
        /*
540
         * The alpha-buffer device requires that we fill the
541
         * entire path as a single unit.
542
         */
543
0
        gx_path_init_local(&spath, pgs->memory);
544
0
        code = gx_stroke_add(pgs->path, &spath, pgs, false);
545
0
        gs_setlinewidth(pgs, orig_width);
546
0
        scale_dash_pattern(pgs, 1.0 / scale);
547
0
        if (code >= 0)
548
0
            code = gx_fill_path(&spath, gs_currentdevicecolor_inline(pgs), pgs,
549
0
                                gx_rule_winding_number,
550
0
                                pgs->fill_adjust.x,
551
0
                                pgs->fill_adjust.y);
552
0
        gs_setflat(pgs, orig_flatness);
553
0
        gx_path_free(&spath, "gs_stroke");
554
0
        if (acode > 0)
555
0
            rcode = alpha_buffer_release(pgs, code >= 0);
556
0
    } else
557
5.37M
        code = gx_stroke_fill(pgs->path, pgs);
558
5.37M
    if (code >= 0 && rcode < 0)
559
0
        code = rcode;
560
561
5.37M
    if (!is_fill_correct) {
562
0
        pgs->is_fill_color = true;
563
0
    }
564
565
5.38M
out:
566
5.38M
    if (black_vector) {
567
        /* Restore color */
568
0
        gsicc_restore_blacktextvec(pgs, false);
569
0
    }
570
5.38M
    return code;
571
5.37M
}
572
573
/* Stroke the current path */
574
int
575
gs_stroke(gs_gstate * pgs)
576
5.38M
{
577
5.38M
    int code;
578
579
    /*
580
     * If we're inside a charpath, just merge the current path
581
     * into the parent's path.
582
     */
583
5.38M
    if (pgs->in_charpath) {
584
0
        if (pgs->in_charpath == cpm_true_charpath) {
585
            /*
586
             * A stroke inside a true charpath should do the
587
             * equivalent of strokepath.
588
             */
589
0
            code = gs_strokepath(pgs);
590
0
            if (code < 0)
591
0
                return code;
592
0
        }
593
0
        code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
594
0
                                     pgs->in_charpath);
595
0
        if (code < 0)
596
0
            return code;
597
0
    }
598
5.38M
    if (!gs_is_null_device(pgs->device)) {
599
5.38M
        code = do_stroke(pgs);
600
5.38M
        if (code < 0)
601
7.98k
            return code;
602
5.38M
    }
603
5.37M
    return gs_newpath(pgs);
604
5.38M
}
605
606
/* Compute the stroked outline of the current path */
607
static int
608
gs_strokepath_aux(gs_gstate * pgs, bool traditional)
609
2.36k
{
610
2.36k
    gx_path spath;
611
2.36k
    int code;
612
613
2.36k
    gx_path_init_local(&spath, pgs->path->memory);
614
2.36k
    code = gx_stroke_add(pgs->path, &spath, pgs, traditional);
615
2.36k
    if (code < 0) {
616
0
        gx_path_free(&spath, "gs_strokepath");
617
0
        return code;
618
0
    }
619
2.36k
    pgs->device->sgr.stroke_stored = false;
620
2.36k
    code = gx_path_assign_free(pgs->path, &spath);
621
2.36k
    if (code < 0)
622
0
        return code;
623
    /* NB: needs testing with PCL */
624
2.36k
    if (gx_path_is_void(pgs->path))
625
1.59k
        pgs->current_point_valid = false;
626
768
    else {
627
768
        gx_setcurrentpoint(pgs, fixed2float(spath.position.x), fixed2float(spath.position.y));
628
768
    }
629
2.36k
    return 0;
630
631
2.36k
}
632
633
int
634
gs_strokepath(gs_gstate * pgs)
635
2.36k
{
636
2.36k
    return gs_strokepath_aux(pgs, true);
637
2.36k
}
638
639
int
640
gs_strokepath2(gs_gstate * pgs)
641
0
{
642
0
    return gs_strokepath_aux(pgs, false);
643
0
}
644
645
static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart)
646
89.6k
{
647
89.6k
    int code, abits, acode = 0, rcode = 0;
648
89.6k
    bool devn;
649
89.6k
    float orig_width, scale, orig_flatness;
650
89.6k
    bool black_vector = false;
651
89.6k
    bool in_smask =
652
89.6k
        (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0;
653
89.6k
    gs_logical_operation_t orig_lop = pgs->log_op;
654
655
    /* It is either our first time, or the stroke was a pattern and
656
       we are coming back from the error if restart < 1 (0 is first
657
       time, 1 stroke is set, and we only need to finish out fill */
658
89.6k
    if (pgs->is_fill_color) {
659
        /* if the fill_color is a pattern, make sure the tile is locked so that */
660
        /* it does not get evicted as the stroke color is loaded.   */
661
89.6k
        if (gx_dc_is_pattern1_color(gs_currentdevicecolor_inline(pgs))) {
662
509
            gs_id id;
663
664
509
            if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
665
247
                id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id;
666
247
                code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, true);
667
262
            } else {
668
262
                code = 0;
669
262
            }
670
509
      if (code < 0)
671
0
    return code; /* lock failed -- tile not in cache? */
672
509
        }
673
89.6k
        gs_swapcolors_quick(pgs); /* switch to the stroke color */
674
89.6k
    }
675
676
89.6k
    if (*restart < 1) {
677
678
        /* We need to distinguish text from vectors to set the object tag.
679
680
           To make that determination, we check for the show graphics state being stored
681
           in the current graphics state. This works even in the case of a glyph from a
682
           Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in
683
           the BuildGlyph/BuildChar procedure. Also, it works in the case of operating
684
           without a glyph cache or bypassing the cache because the glyph is too large or
685
           the cache being already full.
686
687
           Note that it doesn't work for a construction like:
688
           "(xyz) true charpath fill/stroke"
689
           where the show machinations have completed before we get to the fill operation.
690
           This has implications for how we handle PDF text rendering modes 1 and 2. To
691
           handle that, we'll have to add a flag to the path structure, or to the path
692
           segment structure (depending on how fine grained we require it to be).
693
         */
694
89.6k
        if (pgs->show_gstate == NULL && !in_smask) {
695
88.7k
            ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */
696
88.7k
            black_vector = black_vectors(pgs, pgs->device);
697
88.7k
        } else
698
811
            ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
699
700
        /* if we are at restart == 0, we set the stroke color. */
701
89.6k
        code = gx_set_dev_color(pgs);
702
89.6k
        if (code != 0)
703
289
            goto out2;    /* may be gs_error_Remap_color or real error */
704
89.3k
        code = gs_gstate_color_load(pgs);
705
89.3k
        if (code < 0)
706
0
            goto out2;
707
        /* If this was a pattern color, make sure and lock it in the pattern_cache */
708
89.3k
        if (gx_dc_is_pattern1_color(gs_currentdevicecolor_inline(pgs))) {
709
0
            gs_id id;
710
711
0
            if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
712
0
                id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id;
713
0
                code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, true);
714
0
            } else {
715
0
                code = 0;
716
0
            }
717
0
            if (code < 0)
718
0
                goto out2; /* lock failed -- tile not in cache? */
719
0
        }
720
89.3k
    }
721
722
89.3k
    if (pgs->stroke_overprint || (!pgs->stroke_overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
723
89.1k
        gxdso_overprint_active, NULL, 0))) {
724
137
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
725
137
            "[overprint] StrokeFill Stroke Set Overprint\n");
726
137
        code = gs_do_set_overprint(pgs);
727
137
        if (code < 0)
728
0
            goto out2;
729
137
    }
730
89.3k
    *restart = 1;   /* finished, successfully with stroke_color */
731
732
89.3k
    gs_swapcolors_quick(pgs); /* switch to fill color */
733
734
    /* Have to set the fill color too */
735
89.3k
    if (pgs->show_gstate == NULL)
736
88.5k
        ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG);  /* NB: may unset_dev_color */
737
727
    else
738
727
        ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
739
740
89.3k
    code = gx_set_dev_color(pgs);
741
89.3k
    if (code != 0) {
742
477
        goto out2;
743
477
    }
744
88.8k
    code = gs_gstate_color_load(pgs);
745
88.8k
    if (code < 0) {
746
        /* color is set for fill, but a failure here is a problem */
747
        /* i.e., something other than error_Remap_Color */
748
0
        *restart = 2; /* we shouldn't re-enter with '2' */
749
0
        goto out;
750
0
    }
751
752
88.8k
    if (pgs->overprint || (!pgs->overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
753
88.6k
        gxdso_overprint_active, NULL, 0))) {
754
157
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
755
157
            "[overprint] StrokeFill Fill Set Overprint\n");
756
157
        code = gs_do_set_overprint(pgs);
757
157
        if (code < 0)
758
0
            goto out;   /* fatal */
759
157
    }
760
761
88.8k
    abits = 0;
762
88.8k
    {
763
88.8k
        gx_device_color *col_fill = gs_currentdevicecolor_inline(pgs);
764
88.8k
        gx_device_color *col_stroke = gs_swappeddevicecolor_inline(pgs);
765
88.8k
        devn = color_is_devn(col_fill) && color_is_devn(col_stroke);
766
        /* could be devn and masked_devn */
767
88.8k
        if ((color_is_pure(col_fill) && color_is_pure(col_stroke)) || devn)
768
78.8k
            abits = alpha_buffer_bits(pgs);
769
88.8k
    }
770
88.8k
    if (abits > 1) {
771
        /*
772
         * Expand the bounding box by the line width.
773
         * This is expensive to compute, so we only do it
774
         * if we know we're going to buffer.
775
         */
776
0
        float new_width;
777
0
        fixed extra_adjust;
778
0
        float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
779
0
        float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
780
0
        pgs->log_op |= lop_pdf14; /* Force stroking to happen all in 1 go */
781
0
        scale = (float)(1 << (abits / 2));
782
0
        orig_width = gs_currentlinewidth(pgs);
783
0
        new_width = orig_width * scale;
784
0
        extra_adjust =
785
0
                float2fixed(max(xxyy, xyyx) * new_width / 2);
786
0
        orig_flatness = gs_currentflat(pgs);
787
788
        /* Scale up the line width, dash pattern, and flatness. */
789
0
        if (extra_adjust < fixed_1)
790
0
            extra_adjust = fixed_1;
791
0
        acode = alpha_buffer_init(pgs,
792
0
                                  pgs->fill_adjust.x + extra_adjust,
793
0
                                  pgs->fill_adjust.y + extra_adjust,
794
0
                                  abits, devn);
795
0
        if (acode == 2) /* Special case for no fill required */
796
0
            goto out;
797
0
        if (acode < 0)
798
0
            goto out;
799
0
        gs_setlinewidth(pgs, new_width);
800
0
        scale_dash_pattern(pgs, scale);
801
0
        gs_setflat(pgs, (double)(orig_flatness * scale));
802
0
    } else
803
88.8k
        acode = 0;
804
88.8k
    code = gx_fill_stroke_path(pgs, rule);
805
88.8k
    if (abits > 1)
806
0
    {
807
0
        gs_setlinewidth(pgs, orig_width);
808
0
        scale_dash_pattern(pgs, 1.0 / scale);
809
0
        gs_setflat(pgs, orig_flatness);
810
0
        acode = alpha_buffer_release(pgs, code >= 0);
811
0
        pgs->log_op = orig_lop;
812
0
    }
813
88.8k
    if (pgs->is_fill_color) {
814
        /* The color _should_ be the fill color, so make sure it is unlocked  */
815
88.8k
        if (gx_dc_is_pattern1_color(gs_currentdevicecolor_inline(pgs))) {
816
1.64k
            gs_id id;
817
818
1.64k
            if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
819
724
                id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id;
820
724
                code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, false);
821
921
            } else {
822
921
                code = 0;
823
921
            }
824
1.64k
      if (code < 0)
825
0
        goto out2; /* lock failed -- tile not in cache? */
826
1.64k
        }
827
88.8k
    }
828
88.8k
out:
829
88.8k
    if (black_vector) {
830
        /* Restore color */
831
0
        gsicc_restore_blacktextvec(pgs, false);
832
0
    }
833
834
88.8k
    if (gx_dc_is_pattern1_color(gs_swappeddevicecolor_inline(pgs))) {
835
0
        gs_id id;
836
837
0
        if (gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
838
0
            id = gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile->id;
839
0
            rcode = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, false);
840
0
            if (rcode < 0)
841
0
          return rcode; /* unlock failed -- shouldn't be possible */
842
0
        } else {
843
0
            code = 0;
844
0
        }
845
0
    }
846
88.8k
    if (code >= 0 && acode < 0)
847
0
        code = acode;
848
88.8k
    return code;
849
850
766
out2:
851
766
    if (black_vector) {
852
        /* Restore color */
853
0
        gsicc_restore_blacktextvec(pgs, false);
854
0
    }
855
766
    return code;
856
88.8k
}
857
858
/* Fill the current path using a specified rule. */
859
static int
860
fill_stroke_with_rule(gs_gstate * pgs, int rule, int *restart)
861
89.6k
{
862
89.6k
    int code;
863
864
    /* If we're inside a charpath, just merge the current path */
865
    /* into the parent's path. */
866
89.6k
    if (pgs->in_charpath) {
867
        /* If we're rendering a glyph cached, the show machinery decides
868
         * whether to actually image it on the output or not, but uncached
869
         * will render directly to the output, so for text rendering
870
         * mode 3, we have to short circuit it here, but keep the
871
         * current point
872
         */
873
0
        *restart = 0;
874
0
        code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
875
0
                                     pgs->in_charpath);
876
0
        if (code < 0)
877
0
            return code;
878
0
        if (pgs->in_charpath == cpm_true_charpath) {
879
            /*
880
             * A stroke inside a true charpath should do the
881
             * equivalent of strokepath.
882
             */
883
0
            code = gs_strokepath(pgs);
884
0
            if (code < 0)
885
0
                return code;
886
0
            code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
887
0
                                         pgs->in_charpath);
888
0
            if (code < 0)
889
0
                return code;
890
0
        }
891
0
    }
892
89.6k
    else if (gs_is_null_device(pgs->device) ||
893
89.6k
             (pgs->show_gstate && pgs->text_rendering_mode == 3 &&
894
0
              pgs->in_cachedevice == CACHE_DEVICE_NOT_CACHING)) {
895
        /* Text Rendering Mode = 3 => Neither stroke, nor fill */
896
        /* Handle separately to prevent gs_gstate_color_load - bug 688308. */
897
0
        *restart = 0;
898
0
        gs_newpath(pgs);
899
0
        code = 0;
900
89.6k
    } else {
901
89.6k
        code = do_fill_stroke(pgs, rule, restart);
902
89.6k
        if (code >= 0)
903
88.8k
            gs_newpath(pgs);
904
89.6k
    }
905
89.6k
    return code;
906
89.6k
}
907
/* Fill using the winding number rule */
908
int
909
gs_fillstroke(gs_gstate * pgs, int *restart)
910
86.3k
{
911
86.3k
    pgs->device->sgr.stroke_stored = false;
912
86.3k
    return fill_stroke_with_rule(pgs, gx_rule_winding_number, restart);
913
86.3k
}
914
/* Fill using the even/odd rule */
915
int
916
gs_eofillstroke(gs_gstate * pgs, int *restart)
917
3.22k
{
918
3.22k
    pgs->device->sgr.stroke_stored = false;
919
3.22k
    return fill_stroke_with_rule(pgs, gx_rule_even_odd, restart);
920
3.22k
}