Coverage Report

Created: 2026-04-01 07:17

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