Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gspaint.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, 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
212
{
60
    /*
61
     * We can't just fill with device white; we must take the
62
     * transfer function into account.
63
     */
64
212
    int code;
65
66
212
    if ((code = gs_gsave(pgs)) < 0)
67
0
        return code;
68
212
    if ((code = gs_setgray(pgs, 1.0)) >= 0) {
69
        /* Fill the page directly, ignoring clipping. */
70
212
        code = gs_fillpage(pgs);
71
212
    }
72
212
    gs_grestore(pgs);
73
212
    return code;
74
212
}
75
76
/* Fill the page with the current color. */
77
int
78
gs_fillpage(gs_gstate * pgs)
79
539k
{
80
539k
    gx_device *dev = gs_currentdevice(pgs);
81
539k
    int code;
82
83
    /*
84
     * No need to check for returning error code,
85
     * existing device will continue to operate as before.
86
     */
87
539k
    epo_check_and_install(dev);
88
89
    /* Deliberately use the terminal device here */
90
539k
    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
539k
    gx_unset_dev_color(pgs);    /* force update so we pick up the new tag */
98
539k
    gx_unset_alt_dev_color(pgs);
99
539k
    dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_UNTOUCHED_TAG);
100
101
539k
    code = gx_set_dev_color(pgs);
102
539k
    if (code != 0)
103
0
        return code;
104
105
539k
    code = (*dev_proc(dev, fillpage))(dev, pgs, gs_currentdevicecolor_inline(pgs));
106
539k
    if (code < 0)
107
2
        return code;
108
109
    /* If GrayDetection is set, make sure monitoring is enabled. */
110
539k
    if (dev->icc_struct != NULL &&
111
539k
            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
539k
    if (code < 0)
116
0
        return code;
117
539k
    return (*dev_proc(dev, sync_output)) (dev);
118
539k
}
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
0
    mem = pgs->memory;
236
0
    mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
237
0
                           "alpha_buffer_init");
238
0
    if (mdev == 0)
239
0
        return 0;   /* if no room, don't buffer */
240
    /* We may have to update the marking parameters if we have a pdf14 device
241
       as our target.  Need to do while dev is still active in pgs */
242
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) {
243
0
        gs_update_trans_marking_params(pgs);
244
0
    }
245
0
    gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale,
246
0
                            alpha_bits, ibox.p.x << log2_scale.x, devn);
247
0
    mdev->width = width;
248
0
    mdev->height = height;
249
0
    mdev->bitmap_memory = mem;
250
0
    if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) {
251
        /* No room for bits, punt. */
252
0
        gs_free_object(mem, mdev, "alpha_buffer_init");
253
0
        return 0;
254
0
    }
255
0
    gx_set_device_only(pgs, (gx_device *) mdev);
256
0
    scale_paths(pgs, log2_scale.x, log2_scale.y, true);
257
0
    return 1;
258
0
}
259
260
/* Release an alpha buffer. */
261
static int
262
alpha_buffer_release(gs_gstate * pgs, bool newpath)
263
0
{
264
0
    gx_device_memory *mdev =
265
0
        (gx_device_memory *) gs_currentdevice_inline(pgs);
266
0
    int code = (*dev_proc(mdev, close_device)) ((gx_device *) mdev);
267
268
0
    if (code >= 0)
269
0
        scale_paths(pgs, -mdev->log2_scale.x, -mdev->log2_scale.y,
270
0
                !(newpath && !gx_path_is_shared(pgs->path)));
271
    /* Reference counting will free mdev. */
272
0
    gx_set_device_only(pgs, mdev->target);
273
0
    return code;
274
0
}
275
276
/* Setup for black vector handling */
277
static inline bool black_vectors(gs_gstate *pgs, gx_device *dev)
278
3.38M
{
279
3.38M
    if (dev->icc_struct != NULL && dev->icc_struct->blackvector &&
280
3.38M
        pgs->black_textvec_state == NULL) {
281
0
        return gsicc_setup_blacktextvec(pgs, dev, false);
282
0
    }
283
3.38M
    return false;
284
3.38M
}
285
286
static int do_fill(gs_gstate *pgs, int rule)
287
3.41M
{
288
3.41M
    int code, abits, acode, rcode = 0;
289
3.41M
    bool devn;
290
3.41M
    bool black_vector = false;
291
3.41M
    bool in_smask =
292
3.41M
        (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0;
293
294
    /* We need to distinguish text from vectors to set the object tag.
295
296
       To make that determination, we check for the show graphics state being stored
297
       in the current graphics state. This works even in the case of a glyph from a
298
       Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in
299
       the BuildGlyph/BuildChar procedure. Also, it works in the case of operating
300
       without a glyph cache or bypassing the cache because the glyph is too large or
301
       the cache being already full.
302
303
       Note that it doesn't work for a construction like:
304
       "(xyz) true charpath fill/stroke"
305
       where the show machinations have completed before we get to the fill operation.
306
       This has implications for how we handle PDF text rendering modes 1 and 2. To
307
       handle that, we'll have to add a flag to the path structure, or to the path
308
       segment structure (depending on how fine grained we require it to be).
309
     */
310
3.41M
    if (pgs->show_gstate == NULL && !in_smask) {
311
2.49M
        ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */
312
2.49M
        black_vector = black_vectors(pgs, pgs->device); /* Set vector fill to black */
313
2.49M
    } else
314
915k
        ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
315
316
3.41M
    code = gx_set_dev_color(pgs);
317
3.41M
    if (code != 0)
318
66.8k
        goto out;
319
3.34M
    code = gs_gstate_color_load(pgs);
320
3.34M
    if (code < 0)
321
0
        goto out;
322
323
3.34M
    if (pgs->overprint || (!pgs->overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
324
3.30M
        gxdso_overprint_active, NULL, 0))) {
325
41.9k
        gs_overprint_params_t op_params = { 0 };
326
327
41.9k
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
328
41.9k
            "[overprint] Fill Overprint\n");
329
41.9k
        code = gs_do_set_overprint(pgs);
330
41.9k
        if (code < 0)
331
0
            goto out;
332
333
41.9k
        op_params.op_state = OP_STATE_FILL;
334
41.9k
        gs_gstate_update_overprint(pgs, &op_params);
335
41.9k
    }
336
337
3.34M
    abits = 0;
338
3.34M
    {
339
3.34M
        gx_device_color *col = gs_currentdevicecolor_inline(pgs);
340
3.34M
        devn = color_is_devn(col);
341
3.34M
        if (color_is_pure(col) || devn)
342
2.77M
            abits = alpha_buffer_bits(pgs);
343
3.34M
    }
344
3.34M
    if (abits > 1) {
345
0
        acode = alpha_buffer_init(pgs, pgs->fill_adjust.x,
346
0
                                  pgs->fill_adjust.y, abits, devn);
347
0
        if (acode == 2) { /* Special case for no fill required */
348
0
            code = 0;
349
0
            goto out;
350
0
        }
351
0
        if (acode < 0) {
352
0
            code = acode;
353
0
            goto out;
354
0
        }
355
0
    } else
356
3.34M
        acode = 0;
357
3.34M
    code = gx_fill_path(pgs->path, gs_currentdevicecolor_inline(pgs), pgs, rule,
358
3.34M
                        pgs->fill_adjust.x, pgs->fill_adjust.y);
359
3.34M
    if (acode > 0)
360
0
        rcode = alpha_buffer_release(pgs, code >= 0);
361
3.34M
    if (code >= 0 && rcode < 0)
362
0
        code = rcode;
363
364
3.41M
out:
365
3.41M
    if (black_vector) {
366
        /* Restore color */
367
0
        gsicc_restore_blacktextvec(pgs, false);
368
0
    }
369
370
3.41M
    return code;
371
3.34M
}
372
373
/* Fill the current path using a specified rule. */
374
static int
375
fill_with_rule(gs_gstate * pgs, int rule)
376
3.41M
{
377
3.41M
    int code;
378
379
    /* If we're inside a charpath, just merge the current path */
380
    /* into the parent's path. */
381
3.41M
    if (pgs->in_charpath)
382
0
        code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
383
0
                                     pgs->in_charpath);
384
            /* If we're rendering a glyph cached, the show machinery decides
385
             * whether to actually image it on the output or not, but uncached
386
             * will render directly to the output, so for text rendering
387
             * mode 3, we have to short circuit it here, but keep the
388
             * current point
389
             */
390
3.41M
    else if (gs_is_null_device(pgs->device)
391
3.41M
            || (pgs->show_gstate && pgs->text_rendering_mode == 3
392
3.41M
            && pgs->in_cachedevice == CACHE_DEVICE_NOT_CACHING)) {
393
        /* Handle separately to prevent gs_gstate_color_load - bug 688308. */
394
0
        gs_newpath(pgs);
395
0
        code = 0;
396
3.41M
    } else {
397
3.41M
        code = do_fill(pgs, rule);
398
3.41M
        if (code >= 0)
399
3.34M
            code = gs_newpath(pgs);
400
3.41M
    }
401
3.41M
    return code;
402
3.41M
}
403
/* Fill using the winding number rule */
404
int
405
gs_fill(gs_gstate * pgs)
406
3.37M
{
407
3.37M
    pgs->device->sgr.stroke_stored = false;
408
3.37M
    return fill_with_rule(pgs, gx_rule_winding_number);
409
3.37M
}
410
/* Fill using the even/odd rule */
411
int
412
gs_eofill(gs_gstate * pgs)
413
34.0k
{
414
34.0k
    pgs->device->sgr.stroke_stored = false;
415
34.0k
    return fill_with_rule(pgs, gx_rule_even_odd);
416
34.0k
}
417
418
static int
419
do_stroke(gs_gstate * pgs)
420
867k
{
421
867k
    int code, abits, acode, rcode = 0;
422
867k
    bool devn;
423
867k
    bool is_fill_correct = true;
424
867k
    bool black_vector = false;
425
867k
    bool in_smask =
426
867k
        (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0;
427
428
429
    /* We need to distinguish text from vectors to set the object tag.
430
431
       To make that determination, we check for the show graphics state being stored
432
       in the current graphics state. This works even in the case of a glyph from a
433
       Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in
434
       the BuildGlyph/BuildChar procedure. Also, it works in the case of operating
435
       without a glyph cache or bypassing the cache because the glyph is too large or
436
       the cache being already full.
437
438
       Note that it doesn't work for a construction like:
439
       "(xyz) true charpath fill/stroke"
440
       where the show machinations have completed before we get to the fill operation.
441
       This has implications for how we handle PDF text rendering modes 1 and 2. To
442
       handle that, we'll have to add a flag to the path structure, or to the path
443
       segment structure (depending on how fine grained we require it to be).
444
     */
445
867k
    if (pgs->show_gstate == NULL && !in_smask) {
446
866k
        ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */
447
866k
        black_vector = black_vectors(pgs, pgs->device);
448
866k
    } else
449
543
        ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
450
451
867k
    code = gx_set_dev_color(pgs);
452
867k
    if (code != 0)
453
2.03k
        goto out;
454
865k
    code = gs_gstate_color_load(pgs);
455
865k
    if (code < 0)
456
0
        goto out;
457
458
459
865k
    if (pgs->stroke_overprint || (!pgs->stroke_overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
460
847k
        gxdso_overprint_active, NULL, 0))) {
461
18.1k
        gs_overprint_params_t op_params = { 0 };
462
463
        /* PS2 does not have the concept of fill and stroke colors. Here we need to possibly correct
464
           for that in the graphic state during this operation */
465
18.1k
        if (pgs->is_fill_color) {
466
0
            is_fill_correct = false;
467
0
            pgs->is_fill_color = false;
468
0
        }
469
470
471
18.1k
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
472
18.1k
            "[overprint] Stroke Overprint\n");
473
18.1k
        code = gs_do_set_overprint(pgs);
474
18.1k
        if (code < 0) {
475
0
            if (!is_fill_correct) {
476
0
                pgs->is_fill_color = true;
477
0
            }
478
0
            goto out;
479
0
        }
480
481
18.1k
        op_params.op_state = OP_STATE_STROKE;
482
18.1k
        gs_gstate_update_overprint(pgs, &op_params);
483
18.1k
    }
484
485
865k
    abits = 0;
486
865k
    {
487
865k
        gx_device_color *col = gs_currentdevicecolor_inline(pgs);
488
865k
        devn = color_is_devn(col);
489
865k
        if (color_is_pure(col) || devn)
490
784k
            abits = alpha_buffer_bits(pgs);
491
865k
    }
492
865k
    if (abits > 1) {
493
        /*
494
         * Expand the bounding box by the line width.
495
         * This is expensive to compute, so we only do it
496
         * if we know we're going to buffer.
497
         */
498
0
        float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
499
0
        float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
500
0
        float scale = (float)(1 << (abits / 2));
501
0
        float orig_width = gs_currentlinewidth(pgs);
502
0
        float new_width = orig_width * scale;
503
0
        fixed extra_adjust =
504
0
                float2fixed(max(xxyy, xyyx) * new_width / 2);
505
0
        float orig_flatness = gs_currentflat(pgs);
506
0
        gx_path spath;
507
508
        /* Scale up the line width, dash pattern, and flatness. */
509
0
        if (extra_adjust < fixed_1)
510
0
            extra_adjust = fixed_1;
511
0
        acode = alpha_buffer_init(pgs,
512
0
                                  pgs->fill_adjust.x + extra_adjust,
513
0
                                  pgs->fill_adjust.y + extra_adjust,
514
0
                                  abits, devn);
515
0
        if (acode == 2) {            /* Special code meaning no fill required */
516
0
            if (!is_fill_correct) {
517
0
                pgs->is_fill_color = true;
518
0
            }
519
0
            code = 0;
520
0
            goto out;
521
0
        }
522
0
        if (acode < 0) {
523
0
            if (!is_fill_correct) {
524
0
                pgs->is_fill_color = true;
525
0
            }
526
0
            code = acode;
527
0
            goto out;
528
0
        }
529
0
        gs_setlinewidth(pgs, new_width);
530
0
        scale_dash_pattern(pgs, scale);
531
0
        gs_setflat(pgs, (double)(orig_flatness * scale));
532
        /*
533
         * The alpha-buffer device requires that we fill the
534
         * entire path as a single unit.
535
         */
536
0
        gx_path_init_local(&spath, pgs->memory);
537
0
        code = gx_stroke_add(pgs->path, &spath, pgs, false);
538
0
        gs_setlinewidth(pgs, orig_width);
539
0
        scale_dash_pattern(pgs, 1.0 / scale);
540
0
        if (code >= 0)
541
0
            code = gx_fill_path(&spath, gs_currentdevicecolor_inline(pgs), pgs,
542
0
                                gx_rule_winding_number,
543
0
                                pgs->fill_adjust.x,
544
0
                                pgs->fill_adjust.y);
545
0
        gs_setflat(pgs, orig_flatness);
546
0
        gx_path_free(&spath, "gs_stroke");
547
0
        if (acode > 0)
548
0
            rcode = alpha_buffer_release(pgs, code >= 0);
549
0
    } else
550
865k
        code = gx_stroke_fill(pgs->path, pgs);
551
865k
    if (code >= 0 && rcode < 0)
552
0
        code = rcode;
553
554
865k
    if (!is_fill_correct) {
555
0
        pgs->is_fill_color = true;
556
0
    }
557
558
867k
out:
559
867k
    if (black_vector) {
560
        /* Restore color */
561
0
        gsicc_restore_blacktextvec(pgs, false);
562
0
    }
563
867k
    return code;
564
865k
}
565
566
/* Stroke the current path */
567
int
568
gs_stroke(gs_gstate * pgs)
569
867k
{
570
867k
    int code;
571
572
    /*
573
     * If we're inside a charpath, just merge the current path
574
     * into the parent's path.
575
     */
576
867k
    if (pgs->in_charpath) {
577
0
        if (pgs->in_charpath == cpm_true_charpath) {
578
            /*
579
             * A stroke inside a true charpath should do the
580
             * equivalent of strokepath.
581
             */
582
0
            code = gs_strokepath(pgs);
583
0
            if (code < 0)
584
0
                return code;
585
0
        }
586
0
        code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
587
0
                                     pgs->in_charpath);
588
0
        if (code < 0)
589
0
            return code;
590
0
    }
591
867k
    if (!gs_is_null_device(pgs->device)) {
592
867k
        code = do_stroke(pgs);
593
867k
        if (code < 0)
594
2.04k
            return code;
595
867k
    }
596
865k
    return gs_newpath(pgs);
597
867k
}
598
599
/* Compute the stroked outline of the current path */
600
static int
601
gs_strokepath_aux(gs_gstate * pgs, bool traditional)
602
161
{
603
161
    gx_path spath;
604
161
    int code;
605
606
161
    gx_path_init_local(&spath, pgs->path->memory);
607
161
    code = gx_stroke_add(pgs->path, &spath, pgs, traditional);
608
161
    if (code < 0) {
609
0
        gx_path_free(&spath, "gs_strokepath");
610
0
        return code;
611
0
    }
612
161
    pgs->device->sgr.stroke_stored = false;
613
161
    code = gx_path_assign_free(pgs->path, &spath);
614
161
    if (code < 0)
615
0
        return code;
616
    /* NB: needs testing with PCL */
617
161
    if (gx_path_is_void(pgs->path))
618
126
        pgs->current_point_valid = false;
619
35
    else {
620
35
        gx_setcurrentpoint(pgs, fixed2float(spath.position.x), fixed2float(spath.position.y));
621
35
    }
622
161
    return 0;
623
624
161
}
625
626
int
627
gs_strokepath(gs_gstate * pgs)
628
161
{
629
161
    return gs_strokepath_aux(pgs, true);
630
161
}
631
632
int
633
gs_strokepath2(gs_gstate * pgs)
634
0
{
635
0
    return gs_strokepath_aux(pgs, false);
636
0
}
637
638
static int do_fill_stroke(gs_gstate *pgs, int rule, int *restart)
639
18.7k
{
640
18.7k
    int code, abits, acode = 0, rcode = 0;
641
18.7k
    bool devn;
642
18.7k
    float orig_width, scale, orig_flatness;
643
18.7k
    bool black_vector = false;
644
18.7k
    bool in_smask =
645
18.7k
        (dev_proc(pgs->device, dev_spec_op)(pgs->device, gxdso_in_smask_construction, NULL, 0)) > 0;
646
647
648
    /* It is either our first time, or the stroke was a pattern and
649
       we are coming back from the error if restart < 1 (0 is first
650
       time, 1 stroke is set, and we only need to finish out fill */
651
18.7k
    if (pgs->is_fill_color) {
652
        /* if the fill_color is a pattern, make sure the tile is locked so that */
653
        /* it does not get evicted as the stroke color is loaded.   */
654
18.7k
        if (gx_dc_is_pattern1_color(gs_currentdevicecolor_inline(pgs))) {
655
30
            gs_id id;
656
657
30
            if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
658
30
                id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id;
659
30
                code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, true);
660
30
            } else {
661
0
                code = 0;
662
0
            }
663
30
      if (code < 0)
664
0
    return code; /* lock failed -- tile not in cache? */
665
30
        }
666
18.7k
        gs_swapcolors_quick(pgs); /* switch to the stroke color */
667
18.7k
    }
668
669
18.7k
    if (*restart < 1) {
670
671
        /* We need to distinguish text from vectors to set the object tag.
672
673
           To make that determination, we check for the show graphics state being stored
674
           in the current graphics state. This works even in the case of a glyph from a
675
           Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in
676
           the BuildGlyph/BuildChar procedure. Also, it works in the case of operating
677
           without a glyph cache or bypassing the cache because the glyph is too large or
678
           the cache being already full.
679
680
           Note that it doesn't work for a construction like:
681
           "(xyz) true charpath fill/stroke"
682
           where the show machinations have completed before we get to the fill operation.
683
           This has implications for how we handle PDF text rendering modes 1 and 2. To
684
           handle that, we'll have to add a flag to the path structure, or to the path
685
           segment structure (depending on how fine grained we require it to be).
686
         */
687
18.7k
        if (pgs->show_gstate == NULL && !in_smask) {
688
18.7k
            ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG); /* NB: may unset_dev_color */
689
18.7k
            black_vector = black_vectors(pgs, pgs->device);
690
18.7k
        } else
691
39
            ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
692
693
        /* if we are at restart == 0, we set the stroke color. */
694
18.7k
        code = gx_set_dev_color(pgs);
695
18.7k
        if (code != 0)
696
59
            goto out2;    /* may be gs_error_Remap_color or real error */
697
18.6k
        code = gs_gstate_color_load(pgs);
698
18.6k
        if (code < 0)
699
0
            goto out2;
700
        /* If this was a pattern color, make sure and lock it in the pattern_cache */
701
18.6k
        if (gx_dc_is_pattern1_color(gs_currentdevicecolor_inline(pgs))) {
702
0
            gs_id id;
703
704
0
            if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
705
0
                id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id;
706
0
                code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, true);
707
0
            } else {
708
0
                code = 0;
709
0
            }
710
0
            if (code < 0)
711
0
                goto out2; /* lock failed -- tile not in cache? */
712
0
        }
713
18.6k
    }
714
715
18.6k
    if (pgs->stroke_overprint || (!pgs->stroke_overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
716
18.6k
        gxdso_overprint_active, NULL, 0))) {
717
0
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
718
0
            "[overprint] StrokeFill Stroke Set Overprint\n");
719
0
        code = gs_do_set_overprint(pgs);
720
0
        if (code < 0)
721
0
            goto out2;
722
0
    }
723
18.6k
    *restart = 1;   /* finished, successfully with stroke_color */
724
725
18.6k
    gs_swapcolors_quick(pgs); /* switch to fill color */
726
727
    /* Have to set the fill color too */
728
18.6k
    if (pgs->show_gstate == NULL)
729
18.6k
        ensure_tag_is_set(pgs, pgs->device, GS_VECTOR_TAG);  /* NB: may unset_dev_color */
730
37
    else
731
37
        ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */
732
733
18.6k
    code = gx_set_dev_color(pgs);
734
18.6k
    if (code != 0) {
735
62
        goto out2;
736
62
    }
737
18.6k
    code = gs_gstate_color_load(pgs);
738
18.6k
    if (code < 0) {
739
        /* color is set for fill, but a failure here is a problem */
740
        /* i.e., something other than error_Remap_Color */
741
0
        *restart = 2; /* we shouldn't re-enter with '2' */
742
0
        goto out;
743
0
    }
744
745
18.6k
    if (pgs->overprint || (!pgs->overprint && dev_proc(pgs->device, dev_spec_op)(pgs->device,
746
18.6k
        gxdso_overprint_active, NULL, 0))) {
747
0
        if_debug0m(gs_debug_flag_overprint, pgs->memory,
748
0
            "[overprint] StrokeFill Fill Set Overprint\n");
749
0
        code = gs_do_set_overprint(pgs);
750
0
        if (code < 0)
751
0
            goto out;   /* fatal */
752
0
    }
753
754
18.6k
    abits = 0;
755
18.6k
    {
756
18.6k
        gx_device_color *col_fill = gs_currentdevicecolor_inline(pgs);
757
18.6k
        gx_device_color *col_stroke = gs_swappeddevicecolor_inline(pgs);
758
18.6k
        devn = color_is_devn(col_fill) && color_is_devn(col_stroke);
759
        /* could be devn and masked_devn */
760
18.6k
        if ((color_is_pure(col_fill) && color_is_pure(col_stroke)) || devn)
761
17.0k
            abits = alpha_buffer_bits(pgs);
762
18.6k
    }
763
18.6k
    if (abits > 1) {
764
        /*
765
         * Expand the bounding box by the line width.
766
         * This is expensive to compute, so we only do it
767
         * if we know we're going to buffer.
768
         */
769
0
        float new_width;
770
0
        fixed extra_adjust;
771
0
        float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
772
0
        float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
773
0
        gs_logical_operation_t orig_lop = pgs->log_op;
774
0
        pgs->log_op |= lop_pdf14; /* Force stroking to happen all in 1 go */
775
0
        scale = (float)(1 << (abits / 2));
776
0
        orig_width = gs_currentlinewidth(pgs);
777
0
        new_width = orig_width * scale;
778
0
        extra_adjust =
779
0
                float2fixed(max(xxyy, xyyx) * new_width / 2);
780
0
        orig_flatness = gs_currentflat(pgs);
781
782
        /* Scale up the line width, dash pattern, and flatness. */
783
0
        if (extra_adjust < fixed_1)
784
0
            extra_adjust = fixed_1;
785
0
        acode = alpha_buffer_init(pgs,
786
0
                                  pgs->fill_adjust.x + extra_adjust,
787
0
                                  pgs->fill_adjust.y + extra_adjust,
788
0
                                  abits, devn);
789
0
        if (acode == 2) /* Special case for no fill required */
790
0
            goto out;
791
0
        if (acode < 0)
792
0
            goto out;
793
0
        gs_setlinewidth(pgs, new_width);
794
0
        scale_dash_pattern(pgs, scale);
795
0
        gs_setflat(pgs, (double)(orig_flatness * scale));
796
0
        pgs->log_op = orig_lop;
797
0
    } else
798
18.6k
        acode = 0;
799
18.6k
    code = gx_fill_stroke_path(pgs, rule);
800
18.6k
    if (abits > 1)
801
0
    {
802
0
        gs_setlinewidth(pgs, orig_width);
803
0
        scale_dash_pattern(pgs, 1.0 / scale);
804
0
        gs_setflat(pgs, orig_flatness);
805
0
        acode = alpha_buffer_release(pgs, code >= 0);
806
0
    }
807
18.6k
    if (pgs->is_fill_color) {
808
        /* The color _should_ be the fill color, so make sure it is unlocked  */
809
18.6k
        if (gx_dc_is_pattern1_color(gs_currentdevicecolor_inline(pgs))) {
810
174
            gs_id id;
811
812
174
            if(gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
813
135
                id = gs_currentdevicecolor_inline(pgs)->colors.pattern.p_tile->id;
814
135
                code = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, false);
815
135
            } else {
816
39
                code = 0;
817
39
            }
818
174
      if (code < 0)
819
0
        goto out2; /* lock failed -- tile not in cache? */
820
174
        }
821
18.6k
    }
822
18.6k
out:
823
18.6k
    if (black_vector) {
824
        /* Restore color */
825
0
        gsicc_restore_blacktextvec(pgs, false);
826
0
    }
827
828
18.6k
    if (gx_dc_is_pattern1_color(gs_swappeddevicecolor_inline(pgs))) {
829
0
        gs_id id;
830
831
0
        if (gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile != NULL) {
832
0
            id = gs_swappeddevicecolor_inline(pgs)->colors.pattern.p_tile->id;
833
0
            rcode = dev_proc(pgs->device, lock_pattern)(pgs->device, pgs, id, false);
834
0
            if (rcode < 0)
835
0
          return rcode; /* unlock failed -- shouldn't be possible */
836
0
        } else {
837
0
            code = 0;
838
0
        }
839
0
    }
840
18.6k
    if (code >= 0 && acode < 0)
841
0
        code = acode;
842
18.6k
    return code;
843
844
121
out2:
845
121
    if (black_vector) {
846
        /* Restore color */
847
0
        gsicc_restore_blacktextvec(pgs, false);
848
0
    }
849
121
    return code;
850
18.6k
}
851
852
/* Fill the current path using a specified rule. */
853
static int
854
fill_stroke_with_rule(gs_gstate * pgs, int rule, int *restart)
855
18.7k
{
856
18.7k
    int code;
857
858
    /* If we're inside a charpath, just merge the current path */
859
    /* into the parent's path. */
860
18.7k
    if (pgs->in_charpath) {
861
        /* If we're rendering a glyph cached, the show machinery decides
862
         * whether to actually image it on the output or not, but uncached
863
         * will render directly to the output, so for text rendering
864
         * mode 3, we have to short circuit it here, but keep the
865
         * current point
866
         */
867
0
        *restart = 0;
868
0
        code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
869
0
                                     pgs->in_charpath);
870
0
        if (code < 0)
871
0
            return code;
872
0
        if (pgs->in_charpath == cpm_true_charpath) {
873
            /*
874
             * A stroke inside a true charpath should do the
875
             * equivalent of strokepath.
876
             */
877
0
            code = gs_strokepath(pgs);
878
0
            if (code < 0)
879
0
                return code;
880
0
            code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
881
0
                                         pgs->in_charpath);
882
0
            if (code < 0)
883
0
                return code;
884
0
        }
885
0
    }
886
18.7k
    else if (gs_is_null_device(pgs->device) ||
887
18.7k
             (pgs->show_gstate && pgs->text_rendering_mode == 3 &&
888
18.7k
              pgs->in_cachedevice == CACHE_DEVICE_NOT_CACHING)) {
889
        /* Text Rendering Mode = 3 => Neither stroke, nor fill */
890
        /* Handle separately to prevent gs_gstate_color_load - bug 688308. */
891
0
        *restart = 0;
892
0
        gs_newpath(pgs);
893
0
        code = 0;
894
18.7k
    } else {
895
18.7k
        code = do_fill_stroke(pgs, rule, restart);
896
18.7k
        if (code >= 0)
897
18.6k
            gs_newpath(pgs);
898
18.7k
    }
899
18.7k
    return code;
900
18.7k
}
901
/* Fill using the winding number rule */
902
int
903
gs_fillstroke(gs_gstate * pgs, int *restart)
904
18.3k
{
905
18.3k
    pgs->device->sgr.stroke_stored = false;
906
18.3k
    return fill_stroke_with_rule(pgs, gx_rule_winding_number, restart);
907
18.3k
}
908
/* Fill using the even/odd rule */
909
int
910
gs_eofillstroke(gs_gstate * pgs, int *restart)
911
398
{
912
398
    pgs->device->sgr.stroke_stored = false;
913
398
    return fill_stroke_with_rule(pgs, gx_rule_even_odd, restart);
914
398
}