Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gsstate.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
/* Miscellaneous graphics state operators for Ghostscript library */
18
#include "gx.h"
19
#include "memory_.h"
20
#include "gserrors.h"
21
#include "gsstruct.h"
22
#include "gsutil.h"             /* for gs_next_ids */
23
#include "gzstate.h"
24
#include "gxcspace.h"           /* here for gscolor2.h */
25
#include "gscolor2.h"
26
#include "gscoord.h"            /* for gs_initmatrix */
27
#include "gscie.h"
28
#include "gxclipsr.h"
29
#include "gxcmap.h"
30
#include "gxdevice.h"
31
#include "gxpcache.h"
32
#include "gzht.h"
33
#include "gzline.h"
34
#include "gspath.h"
35
#include "gzpath.h"
36
#include "gzcpath.h"
37
#include "gsovrc.h"
38
#include "gxcolor2.h"
39
#include "gscolor3.h" /* for gs_smoothness() */
40
#include "gxpcolor.h"
41
#include "gsicc_manage.h"
42
#include "gxdevsop.h"
43
44
/* Forward references */
45
static gs_gstate *gstate_alloc(gs_memory_t *, client_name_t,
46
                               const gs_gstate *);
47
static gs_gstate *gstate_clone_for_gsave(gs_gstate *,
48
                                         client_name_t);
49
static gs_gstate *gstate_clone_for_gstate(const gs_gstate *, gs_memory_t *,
50
                                          client_name_t);
51
static void gstate_free_contents(gs_gstate *);
52
static int gstate_copy(gs_gstate *, const gs_gstate *,
53
                        gs_gstate_copy_reason_t, client_name_t);
54
static void clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t cname);
55
56
/*
57
 * Graphics state storage management is complicated.  There are many
58
 * different classes of storage associated with a graphics state:
59
 *
60
 * (1) The gstate object itself.  This includes some objects physically
61
 *      embedded within the gstate object, but because of garbage collection
62
 *      requirements, there are no embedded objects that can be
63
 *      referenced by non-transient pointers.  We assume that the gstate
64
 *      stack "owns" its gstates and that we can free the top gstate when
65
 *      doing a restore.
66
 *
67
 * (2) Objects that are referenced directly by the gstate and whose lifetime
68
 *      is independent of the gstate.  These are garbage collected, not
69
 *      reference counted, so we don't need to do anything special with them
70
 *      when manipulating gstates.  Currently this includes:
71
 *              font
72
 *
73
 * (3) Objects that are referenced directly by the gstate, may be shared
74
 *      among gstates, and should disappear when no gstates reference them.
75
 *      These fall into two groups:
76
 *
77
 *   (3a) Objects that are logically connected to individual gstates.
78
 *      We use reference counting to manage these.  Currently these are:
79
 *              halftone, dev_ht(4), cie_render, black_generation,
80
 *              undercolor_removal, set_transfer.*, cie_joint_caches,
81
 *              clip_stack, {opacity,shape}.mask
82
 *      effective_transfer.* may point to some of the same objects as
83
 *      set_transfer.*, but don't contribute to the reference count.
84
 *      Similarly, dev_color may point to the dev_ht object.  For
85
 *      simplicity, we initialize all of these pointers to 0 and then
86
 *      allocate the object itself when needed.
87
 *
88
 *   (3b) Objects whose lifetimes are associated with something else.
89
 *      Currently these are:
90
 *              pattern_cache, which is associated with the entire
91
 *                stack, is allocated when first needed, and currently
92
 *                is never freed;
93
 *              view_clip, which is associated with the current
94
 *                save level (effectively, with the gstate sub-stack
95
 *                back to the save) and is managed specially;
96
 *
97
 * (4) Objects that are referenced directly by exactly one gstate and that
98
 *      are not referenced (except transiently) from any other object.
99
 *      These fall into two groups:
100
 *
101
 *   (4b) Objects allocated individually, for the given reason:
102
 *              line_params.dash.pattern (variable-length),
103
 *              color_space, path, clip_path, effective_clip.path,
104
 *              ccolor, dev_color
105
 *                  (may be referenced from image enumerators or elsewhere)
106
 *
107
 *   (4b) The "client data" for a gstate.  For the interpreter, this is
108
 *      the refs associated with the gstate, such as the screen procedures.
109
 *      Client-supplied procedures manage client data.
110
 *
111
 * (5) Objects referenced indirectly from gstate objects of category (4),
112
 *      including objects that may also be referenced directly by the gstate.
113
 *      The individual routines that manipulate these are responsible
114
 *      for doing the right kind of reference counting or whatever.
115
 *      Currently:
116
 *              devices, path, clip_path, and (if different from both clip_path
117
 *                and view_clip) effective_clip.path require
118
 *                gx_path_assign/free, which uses a reference count;
119
 *              color_space and ccolor require cs_adjust_color/cspace_count
120
 *                or cs_adjust_counts, which use a reference count;
121
 *              dev_color has no references to storage that it owns.
122
 *      We count on garbage collection or restore to deallocate
123
 *        sub-objects of halftone.
124
 *
125
 * Note that when after a gsave, the existing gstate references the related
126
 * objects that we allocate at the same time, and the newly allocated gstate
127
 * references the old related objects.  Similarly, during a grestore, we
128
 * free the related objects referenced by the current gstate, but after the
129
 * grestore, we free the saved gstate, not the current one.  However, when
130
 * we allocate gstates off-stack, the newly allocated gstate does reference
131
 * the newly allocated component objects.  Note also that setgstate /
132
 * currentgstate may produce gstates in which different allocators own
133
 * different sub-objects; this is OK, because restore guarantees that there
134
 * won't be any dangling pointers (as long as we don't allow pointers from
135
 * global gstates to local objects).
136
 */
137
138
/*
139
 * Define these elements of the graphics state that are allocated
140
 * individually for each state, except for line_params.dash.pattern.
141
 * Note that effective_clip_shared is not on the list.
142
 */
143
typedef struct gs_gstate_parts_s {
144
    gx_path *path;
145
    gx_clip_path *clip_path;
146
    gx_clip_path *effective_clip_path;
147
    struct {
148
        gs_client_color *ccolor;
149
        gx_device_color *dev_color;
150
    } color[2];
151
} gs_gstate_parts;
152
153
#define GSTATE_ASSIGN_PARTS(pto, pfrom)\
154
24.2M
  ((pto)->path = (pfrom)->path, (pto)->clip_path = (pfrom)->clip_path,\
155
24.2M
   (pto)->effective_clip_path = (pfrom)->effective_clip_path,\
156
24.2M
   (pto)->color[0].ccolor = (pfrom)->color[0].ccolor,\
157
24.2M
   (pto)->color[0].dev_color = (pfrom)->color[0].dev_color,\
158
24.2M
   (pto)->color[1].ccolor = (pfrom)->color[1].ccolor,\
159
24.2M
   (pto)->color[1].dev_color = (pfrom)->color[1].dev_color)
160
161
extern_st(st_gs_gstate); /* for gstate_alloc() */
162
163
/* Copy client data, using the copy_for procedure if available, */
164
/* the copy procedure otherwise. */
165
static int
166
gstate_copy_client_data(const gs_gstate * pgs, void *dto, void *dfrom,
167
                        gs_gstate_copy_reason_t reason)
168
23.3M
{
169
23.3M
    return (pgs->client_procs.copy_for != 0 ?
170
0
            (*pgs->client_procs.copy_for) (dto, dfrom, reason) :
171
23.3M
            (*pgs->client_procs.copy) (dto, dfrom));
172
23.3M
}
173
174
/* ------ Operations on the entire graphics state ------ */
175
176
/*
177
 * Allocate a path for the graphics state.  We use stable memory because
178
 * some PostScript files have Type 3 fonts whose BuildChar procedure
179
 * uses the sequence save ... setcachedevice ... restore, and the path
180
 * built between the setcachedevice and the restore must not be freed.
181
 * If it weren't for this, we don't think stable memory would be needed.
182
 */
183
static gs_memory_t *
184
gstate_path_memory(gs_memory_t *mem)
185
12.3M
{
186
12.3M
    return gs_memory_stable(mem);
187
12.3M
}
188
189
/* Allocate and initialize a graphics state. */
190
gs_gstate *
191
gs_gstate_alloc(gs_memory_t * mem)
192
130k
{
193
130k
    gs_gstate *pgs = gstate_alloc(mem, "gs_gstate_alloc", NULL);
194
130k
    gs_memory_t *path_mem = gstate_path_memory(mem);
195
130k
    int code;
196
197
130k
    if (pgs == 0)
198
0
        return 0;
199
130k
    GS_STATE_INIT_VALUES(pgs, 1.0);
200
    /* Need to set up at least enough to make gs_gstate_free happy */
201
130k
    pgs->saved = 0;
202
130k
    pgs->clip_stack = NULL;
203
130k
    pgs->view_clip = NULL;
204
130k
    pgs->font = NULL;
205
130k
    pgs->root_font = NULL;
206
130k
    pgs->show_gstate = NULL;
207
130k
    pgs->device = NULL;
208
209
    /*
210
     * Just enough of the state is initialized at this point
211
     * that it's OK to call gs_gstate_free if an allocation fails.
212
     */
213
214
130k
    code = gs_gstate_initialize(pgs, mem);
215
130k
    if (code < 0)
216
0
        goto fail;
217
218
    /* Finish initializing the color rendering state. */
219
220
130k
    rc_alloc_struct_1(pgs->halftone, gs_halftone, &st_halftone, mem,
221
130k
                      goto fail, "gs_gstate_alloc(halftone)");
222
130k
    pgs->halftone->type = ht_type_none;
223
224
    /* Initialize other things not covered by initgraphics */
225
226
130k
    pgs->clip_stack = 0;
227
130k
    pgs->view_clip = gx_cpath_alloc(path_mem, "gs_gstate_alloc(view_clip)");
228
130k
    if (pgs->view_clip == NULL)
229
0
        goto fail;
230
130k
    pgs->view_clip->rule = 0;   /* no clipping */
231
130k
    pgs->effective_clip_id = pgs->clip_path->id;
232
130k
    pgs->effective_view_clip_id = gs_no_id;
233
130k
    pgs->in_cachedevice = 0;
234
130k
    pgs->device = 0;            /* setting device adjusts refcts */
235
130k
    code = gs_nulldevice(pgs);
236
130k
    if (code < 0)
237
0
        goto fail;
238
130k
    gs_setfillconstantalpha(pgs, 1.0);
239
130k
    gs_setstrokeconstantalpha(pgs, 1.0);
240
130k
    gs_setalphaisshape(pgs, false);
241
130k
    gs_settransfer(pgs, gs_identity_transfer);
242
130k
    gs_setflat(pgs, 1.0);
243
130k
    gs_setfilladjust(pgs, 0.3, 0.3);
244
130k
    gs_setlimitclamp(pgs, false);
245
130k
    gs_setstrokeadjust(pgs, true);
246
130k
    pgs->font = 0;              /* Not right, but acceptable until the */
247
    /* PostScript code does the first setfont. */
248
130k
    pgs->root_font = 0;         /* ditto */
249
130k
    pgs->in_charpath = (gs_char_path_mode) 0;
250
130k
    pgs->show_gstate = 0;
251
130k
    pgs->level = 0;
252
130k
    if (gs_initgraphics(pgs) >= 0)
253
130k
        return pgs;
254
    /* Something went very wrong. */
255
0
fail:
256
0
    gs_gstate_free(pgs);
257
0
    return 0;
258
130k
}
259
260
/* Set the client data in a graphics state. */
261
/* This should only be done to a newly created state. */
262
void
263
gs_gstate_set_client(gs_gstate * pgs, void *pdata,
264
                    const gs_gstate_client_procs * pprocs, bool client_has_pattern_streams)
265
406k
{
266
406k
    pgs->client_data = pdata;
267
406k
    pgs->client_procs = *pprocs;
268
406k
    pgs->have_pattern_streams = client_has_pattern_streams;
269
406k
}
270
271
/* Get the client data from a graphics state. */
272
#undef gs_gstate_client_data     /* gzstate.h makes this a macro */
273
void *
274
gs_gstate_client_data(const gs_gstate * pgs)
275
10.6M
{
276
10.6M
    return pgs->client_data;
277
10.6M
}
278
279
/* Free the chain of gstates.*/
280
void
281
gs_gstate_free_chain(gs_gstate * pgs)
282
8.44k
{
283
8.44k
   gs_gstate *saved = pgs, *tmp;
284
285
16.8k
   while(saved != 0) {
286
8.44k
       tmp = saved->saved;
287
8.44k
       gs_gstate_free(saved);
288
8.44k
       saved = tmp;
289
8.44k
   }
290
8.44k
}
291
292
/* Free a graphics state. */
293
void
294
gs_gstate_free(gs_gstate * pgs)
295
801k
{
296
801k
    if (pgs == NULL)
297
0
        return;
298
801k
    gstate_free_contents(pgs);
299
801k
    gs_free_object(pgs->memory, pgs, "gs_gstate_free");
300
801k
}
301
302
/* Save the graphics state. */
303
int
304
gs_gsave(gs_gstate * pgs)
305
11.3M
{
306
11.3M
    gs_gstate *pnew = gstate_clone_for_gsave(pgs, "gs_gsave");
307
308
11.3M
    if (pnew == NULL)
309
229
        return_error(gs_error_VMerror);
310
    /* As of PLRM3, the interaction between gsave and the clip stack is
311
     * now clear. gsave stores the clip stack into the saved graphics
312
     * state, but then clears it in the current graphics state.
313
     *
314
     * Ordinarily, reference count rules would indicate an rc_decrement()
315
     * on pgs->clip_stack, but gstate_clone() has an exception for
316
     * the clip_stack field.
317
     */
318
11.3M
    pgs->clip_stack = NULL;
319
11.3M
    pgs->saved = pnew;
320
11.3M
    if (pgs->show_gstate == pgs)
321
0
        pgs->show_gstate = pnew->show_gstate = pnew;
322
11.3M
    pgs->trans_flags.xstate_change = false;
323
11.3M
    pgs->level++;
324
11.3M
    if_debug2m('g', pgs->memory, "[g]gsave -> "PRI_INTPTR", level = %d\n",
325
11.3M
              (intptr_t)pnew, pgs->level);
326
11.3M
    return 0;
327
11.3M
}
328
329
/*
330
 * Save the graphics state for a 'save'.
331
 * We cut the stack below the new gstate, and return the old one.
332
 * In addition to an ordinary gsave, we create a new view clip path.
333
 */
334
int
335
gs_gsave_for_save(gs_gstate * pgs, gs_gstate ** psaved)
336
199k
{
337
199k
    int code;
338
199k
    gx_clip_path *old_cpath = pgs->view_clip;
339
199k
    gx_clip_path *new_cpath;
340
341
199k
    if (old_cpath) {
342
199k
        new_cpath =
343
199k
            gx_cpath_alloc_shared(old_cpath, pgs->memory,
344
199k
                                  "gs_gsave_for_save(view_clip)");
345
199k
        if (new_cpath == 0)
346
0
            return_error(gs_error_VMerror);
347
199k
    } else {
348
0
        new_cpath = 0;
349
0
    }
350
199k
    code = gs_gsave(pgs);
351
199k
    if (code < 0)
352
0
        goto fail;
353
199k
    if (pgs->effective_clip_path == pgs->view_clip)
354
0
        pgs->effective_clip_path = new_cpath;
355
199k
    pgs->view_clip = new_cpath;
356
    /* Cut the stack so we can't grestore past here. */
357
199k
    *psaved = pgs->saved;
358
199k
    pgs->saved = 0;
359
360
199k
    code = gs_gsave(pgs);
361
199k
    if (code < 0) {
362
0
        pgs->saved = *psaved;
363
0
        *psaved = NULL;
364
0
        gs_grestore(pgs);
365
0
        return code;
366
0
    }
367
199k
    return code;
368
0
fail:
369
0
    if (new_cpath)
370
0
        gx_cpath_free(new_cpath, "gs_gsave_for_save(view_clip)");
371
0
    return code;
372
199k
}
373
374
/* Restore the graphics state. Can fully empty graphics stack */
375
int     /* return 0 if ok, 1 if stack was empty */
376
gs_grestore_only(gs_gstate * pgs)
377
11.2M
{
378
11.2M
    gs_gstate *saved = pgs->saved;
379
11.2M
    gs_gstate tmp_gstate;
380
11.2M
    void *pdata = pgs->client_data;
381
11.2M
    void *sdata;
382
383
11.2M
    if_debug2m('g', pgs->memory, "[g]grestore "PRI_INTPTR", level was %d\n",
384
11.2M
               (intptr_t)saved, pgs->level);
385
11.2M
    if (!saved)
386
0
        return 1;
387
11.2M
    sdata = saved->client_data;
388
11.2M
    if (saved->pattern_cache == 0)
389
40.8k
        saved->pattern_cache = pgs->pattern_cache;
390
    /* Swap back the client data pointers. */
391
11.2M
    pgs->client_data = sdata;
392
11.2M
    saved->client_data = pdata;
393
11.2M
    if (pdata != 0 && sdata != 0)
394
11.2M
        gstate_copy_client_data(pgs, pdata, sdata, copy_for_grestore);
395
11.2M
    gstate_free_contents(pgs);
396
11.2M
    tmp_gstate = *pgs;              /* temp after contents freed (with pointers zeroed) */
397
11.2M
    *pgs = *saved;
398
11.2M
    if (pgs->show_gstate == saved)
399
0
        pgs->show_gstate = pgs;
400
11.2M
    *saved = tmp_gstate;            /* restore "freed" state (pointers zeroed after contents freed) */
401
11.2M
    gs_free_object(pgs->memory, saved, "gs_grestore");
402
403
11.2M
    return 0;
404
11.2M
}
405
406
/* Restore the graphics state per PostScript semantics */
407
int
408
gs_grestore(gs_gstate * pgs)
409
11.1M
{
410
11.1M
    int code;
411
11.1M
    if (!pgs->saved)
412
0
        return gs_gsave(pgs);   /* shouldn't ever happen */
413
11.1M
    code = gs_grestore_only(pgs);
414
11.1M
    if (code < 0)
415
0
        return code;
416
417
    /* Wraparound: make sure there are always >= 1 saves on stack */
418
11.1M
    if (pgs->saved)
419
11.1M
        return 0;
420
5.18k
    return gs_gsave(pgs);
421
11.1M
}
422
423
/* Restore the graphics state for a 'restore', splicing the old stack */
424
/* back on.  Note that we actually do a grestoreall + 2 grestores. */
425
int
426
gs_grestoreall_for_restore(gs_gstate * pgs, gs_gstate * saved)
427
199k
{
428
199k
    int code;
429
430
209k
    while (pgs->saved->saved) {
431
9.95k
        code = gs_grestore(pgs);
432
9.95k
        if (code < 0)
433
0
            return code;
434
9.95k
    }
435
    /* Make sure we don't leave dangling pointers in the caches. */
436
199k
    if (pgs->pattern_cache)
437
199k
        (*pgs->pattern_cache->free_all) (pgs->pattern_cache);
438
199k
    pgs->saved->saved = saved;
439
199k
    code = gs_grestore(pgs);
440
199k
    if (code < 0)
441
0
        return code;
442
199k
    if (pgs->view_clip) {
443
199k
        gx_cpath_free(pgs->view_clip, "gs_grestoreall_for_restore");
444
199k
        pgs->view_clip = 0;
445
199k
    }
446
199k
    return gs_grestore(pgs);
447
199k
}
448
449
/* Restore to the bottommost graphics state (at this save level). */
450
int
451
gs_grestoreall(gs_gstate * pgs)
452
26
{
453
26
    if (!pgs->saved)            /* shouldn't happen */
454
0
        return gs_gsave(pgs);
455
26
    while (pgs->saved->saved) {
456
0
        int code = gs_grestore(pgs);
457
458
0
        if (code < 0)
459
0
            return code;
460
0
    }
461
26
    return gs_grestore(pgs);
462
26
}
463
464
/* Allocate and return a new graphics state. */
465
gs_gstate *
466
gs_gstate_copy(const gs_gstate * pgs, gs_memory_t * mem)
467
761k
{
468
761k
    gs_gstate *pnew;
469
470
761k
    pnew = gstate_clone_for_gstate(pgs, mem, "gs_gstate");
471
761k
    if (pnew == NULL)
472
0
        return NULL;
473
761k
    clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_gstate_copy");
474
761k
    pnew->saved = NULL;
475
    /*
476
     * Prevent dangling references from the show_gstate pointer.  If
477
     * this context is its own show_gstate, set the pointer in the clone
478
     * to point to the clone; otherwise, set the pointer in the clone to
479
     * NULL, and let gs_setgstate fix it up.
480
     */
481
761k
    pnew->show_gstate =
482
761k
        (pgs->show_gstate == pgs ? pnew : NULL);
483
761k
    return pnew;
484
761k
}
485
486
/* Copy one previously allocated graphics state to another. */
487
int
488
gs_copygstate(gs_gstate * pto, const gs_gstate * pfrom)
489
0
{
490
0
    return gstate_copy(pto, pfrom, copy_for_copygstate, "gs_copygstate");
491
0
}
492
493
/* Copy the current graphics state to a previously allocated one. */
494
int
495
gs_currentgstate(gs_gstate * pto, const gs_gstate * pgs)
496
1
{
497
1
    int code =
498
1
        gstate_copy(pto, pgs, copy_for_currentgstate, "gs_currentgstate");
499
500
1
    if (code >= 0)
501
1
        pto->view_clip = 0;
502
1
    return code;
503
1
}
504
505
/* Restore the current graphics state from a previously allocated one. */
506
int
507
gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom)
508
18.1k
{
509
    /*
510
     * The implementation is the same as currentgstate,
511
     * except we must preserve the saved pointer, the level,
512
     * the view clip, and possibly the show_gstate.
513
     */
514
18.1k
    gs_gstate *saved_show = pgs->show_gstate;
515
18.1k
    int level = pgs->level;
516
18.1k
    gx_clip_path *view_clip = pgs->view_clip;
517
18.1k
    int code;
518
519
18.1k
    pgs->view_clip = 0;         /* prevent refcount decrementing */
520
18.1k
    code = gstate_copy(pgs, pfrom, copy_for_setgstate, "gs_setgstate");
521
18.1k
    if (code < 0)
522
0
        return code;
523
18.1k
    pgs->level = level;
524
18.1k
    pgs->view_clip = view_clip;
525
18.1k
    pgs->show_gstate =
526
18.1k
        (pgs->show_gstate == pfrom ? pgs : saved_show);
527
18.1k
    return 0;
528
18.1k
}
529
530
/* Get the allocator pointer of a graphics state. */
531
/* This is provided only for the interpreter */
532
/* and for color space implementation. */
533
gs_memory_t *
534
gs_gstate_memory(const gs_gstate * pgs)
535
153k
{
536
153k
    return pgs->memory;
537
153k
}
538
539
/* Get the saved pointer of the graphics state. */
540
/* This is provided only for Level 2 grestore. */
541
gs_gstate *
542
gs_gstate_saved(const gs_gstate * pgs)
543
333k
{
544
333k
    return pgs->saved;
545
333k
}
546
547
/* Swap the saved pointer of the graphics state. */
548
/* This is provided only for save/restore. */
549
gs_gstate *
550
gs_gstate_swap_saved(gs_gstate * pgs, gs_gstate * new_saved)
551
0
{
552
0
    gs_gstate *saved = pgs->saved;
553
554
0
    pgs->saved = new_saved;
555
0
    return saved;
556
0
}
557
558
/* Swap the memory pointer of the graphics state. */
559
/* This is provided only for the interpreter. */
560
gs_memory_t *
561
gs_gstate_swap_memory(gs_gstate * pgs, gs_memory_t * mem)
562
2
{
563
2
    gs_memory_t *memory = pgs->memory;
564
565
2
    pgs->memory = mem;
566
2
    return memory;
567
2
}
568
569
/* ------ Operations on components ------ */
570
571
/*
572
 * Push an overprint compositor onto the current device. Note that if
573
 * the current device already is an overprint compositor, the
574
 * composite will update its parameters but not create a new
575
 * compositor device.
576
 */
577
int
578
gs_gstate_update_overprint(gs_gstate * pgs, const gs_overprint_params_t * pparams)
579
180k
{
580
180k
    gs_composite_t *    pct = 0;
581
180k
    int                 code;
582
180k
    gx_device *         dev = pgs->device;
583
180k
    gx_device *         ovptdev;
584
585
180k
    code = gs_create_overprint(&pct, pparams, pgs->memory);
586
180k
    if (code >= 0) {
587
180k
        code = dev_proc(dev, composite)( dev,
588
180k
                                                   &ovptdev,
589
180k
                                                   pct,
590
180k
                                                   pgs,
591
180k
                                                   pgs->memory,
592
180k
                                                   NULL);
593
180k
        if (code >= 0 || code == gs_error_handled){
594
180k
            if (code == 1) {
595
0
                gx_set_device_only(pgs, ovptdev);
596
                /* Get rid of extra reference */
597
0
                rc_decrement(ovptdev, "gs_gstate_update_overprint(ovptdev)");
598
0
            }
599
180k
            code = 0;
600
180k
        }
601
180k
    }
602
180k
    if (pct != 0)
603
180k
        gs_free_object(pgs->memory, pct, "gs_gstate_update_overprint");
604
605
    /* the following hack handles devices that don't support compositors */
606
180k
    if (code == gs_error_unknownerror && !pparams->retain_any_comps)
607
0
        code = 0;
608
180k
    return code;
609
180k
}
610
611
/*
612
 * Reset the overprint mode for the current color space and color. This
613
 * routine should be called  whenever the current device (i.e.: color
614
 * model), overprint, overprint mode, color space, or color are modified.
615
 *
616
 * The need reason this routine must be called for changes in the current
617
 * color and must consider the current color involves the Pattern color
618
 * space. In that space, the "color" (pattern) can determine if the base
619
 * color space is used (PatternType 1 with PaintType 2), or may provide
620
 * is own color space (PatternType 1 with PaintType 1, PatternType 2).
621
 *
622
 * The most general situation (PatternType 1 with PaintType 1) cannot be
623
 * handled properly due to limitations of the pattern cache mechanism,
624
 * so in this case overprint is effectively disable by making all color
625
 * components "drawn".
626
 */
627
int
628
gs_do_set_overprint(gs_gstate * pgs)
629
101k
{
630
101k
    const gs_color_space *  pcs = gs_currentcolorspace_inline(pgs);
631
101k
    const gs_client_color * pcc = gs_currentcolor_inline(pgs);
632
101k
    int                     code = 0;
633
634
101k
    if (cs_num_components(pcs) < 0 && pcc->pattern != 0)
635
0
        code = pcc->pattern->type->procs.set_color(pcc, pgs);
636
101k
    else {
637
101k
        gx_device* dev = pgs->device;
638
101k
        cmm_dev_profile_t* dev_profile;
639
101k
        gs_color_space_index pcs_index = gs_color_space_get_index(pcs);
640
641
101k
        dev_proc(dev, get_profile)(dev, &dev_profile);
642
101k
        if (dev_profile->overprint_control == gs_overprint_control_disable)
643
0
            return code;
644
645
        /* Transparency device that supports spots and where we have
646
           sep or devicen colors needs special consideration if the device
647
           is in a additive blend mode.  This could
648
           be written more compactly, but it would be unreadable. */
649
101k
        if (dev_proc(dev, dev_spec_op)(dev, gxdso_pdf14_sep_device, NULL, 0) &&
650
101k
            (dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE) &&
651
101k
            (pcs_index == gs_color_space_index_DeviceN ||
652
51.3k
             pcs_index == gs_color_space_index_Separation)) {
653
0
            if (pcs_index == gs_color_space_index_Separation) {
654
0
                if (!(pcs->params.separation.color_type == SEP_MIX ||
655
0
                      pcs->params.separation.color_type == SEP_ENUM)) {
656
                    /* Sep color is not a spot color.  We can't do OP and trans */
657
0
                    return code;
658
0
                }
659
0
            }
660
0
            if (pcs_index == gs_color_space_index_DeviceN) {
661
0
                if (pcs->params.device_n.color_type != SEP_PURE_SPOT) {
662
                    /* DeviceN has process colors  We can't do OP and trans. */
663
0
                    return code;
664
0
                }
665
0
            }
666
0
        }
667
668
        /* If we have a CIE-based space, use the ICC equivalent space */
669
101k
        if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent != NULL)
670
0
            pcs = pcs->icc_equivalent;
671
672
        /* The spaces that do not allow opm (e.g. ones that are not ICC or DeviceCMYK)
673
           will blow away any true setting later. But we have to be prepared
674
           in case this is a CMYK ICC space for example. Hence we set effective mode
675
           to mode here (Bug 698721)*/
676
101k
        pgs->color[0].effective_opm = pgs->overprint_mode;
677
678
101k
        if_debug2m(gs_debug_flag_overprint, pgs->memory,
679
101k
            "[overprint] gs_do_set_overprint. Preset effective mode. pgs->color[0].effective_opm = %d pgs->color[1].effective_opm = %d\n",
680
101k
            pgs->color[0].effective_opm, pgs->color[1].effective_opm);
681
682
101k
        pcs->type->set_overprint(pcs, pgs);
683
101k
    }
684
101k
    return code;
685
101k
}
686
687
/* setoverprint (non-stroke case) interpreter code
688
   ensures that this is called when appropriate. This
689
   should only be coming when we are doing PS files.
690
   As they don't have separate stroke and fill overprint
691
   controls */
692
void
693
gs_setoverprint(gs_gstate * pgs, bool ovp)
694
1.07M
{
695
1.07M
    pgs->overprint = ovp;
696
1.07M
    pgs->stroke_overprint = ovp;
697
1.07M
}
698
699
/* currentoverprint */
700
bool
701
gs_currentoverprint(const gs_gstate * pgs)
702
538k
{
703
538k
    return pgs->overprint;
704
538k
}
705
706
/* setstrokeoverprint */
707
void
708
gs_setstrokeoverprint(gs_gstate * pgs, bool ovp)
709
120k
{
710
120k
    pgs->stroke_overprint = ovp;
711
120k
}
712
713
/* currentstrokeoverprint */
714
bool
715
gs_currentstrokeoverprint(const gs_gstate * pgs)
716
17.9k
{
717
17.9k
    return pgs->stroke_overprint;
718
17.9k
}
719
720
/* setstrokeoverprint */
721
void
722
gs_setfilloverprint(gs_gstate * pgs, bool ovp)
723
121k
{
724
121k
    pgs->overprint = ovp;
725
121k
}
726
727
/* currentstrokeoverprint */
728
bool
729
gs_currentfilloverprint(const gs_gstate * pgs)
730
11.5k
{
731
11.5k
    return pgs->overprint;
732
11.5k
}
733
734
/* setoverprintmode */
735
int
736
gs_setoverprintmode(gs_gstate * pgs, int mode)
737
99.4k
{
738
99.4k
    if (mode < 0 || mode > 1)
739
1
        return_error(gs_error_rangecheck);
740
99.4k
    pgs->overprint_mode = mode;
741
742
99.4k
    return 0;
743
99.4k
}
744
745
/* currentoverprintmode */
746
int
747
gs_currentoverprintmode(const gs_gstate * pgs)
748
0
{
749
0
    return pgs->overprint_mode;
750
0
}
751
752
void
753
gs_setcpsimode(gs_memory_t *mem, bool mode)
754
0
{
755
0
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
756
757
0
    libctx->core->CPSI_mode = mode;
758
0
}
759
760
/* currentcpsimode */
761
bool
762
gs_currentcpsimode(const gs_memory_t * mem)
763
325M
{
764
325M
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
765
766
325M
    return libctx->core->CPSI_mode;
767
325M
}
768
769
/* The edgebuffer based scanconverter can only cope with values of 0
770
 * or 0.5 (i.e. 'center of pixel' or 'any part of pixel'). These
771
 * are the only values required for correct behaviour according to
772
 * the PDF and PS specs. Therefore, if we are using the edgebuffer
773
 * based scan converter, force these values. */
774
static void
775
sanitize_fill_adjust(gs_gstate * pgs)
776
219k
{
777
219k
    int scanconverter = gs_getscanconverter(pgs->memory);
778
219k
    if (scanconverter >= GS_SCANCONVERTER_EDGEBUFFER || (GS_SCANCONVERTER_DEFAULT_IS_EDGEBUFFER && scanconverter == GS_SCANCONVERTER_DEFAULT)) {
779
219k
        fixed adjust = (pgs->fill_adjust.x >= float2fixed(0.25) || pgs->fill_adjust.y >= float2fixed(0.25) ? fixed_half : 0);
780
219k
        pgs->fill_adjust.x = adjust;
781
219k
        pgs->fill_adjust.y = adjust;
782
219k
    }
783
219k
}
784
785
void
786
gs_setscanconverter(gs_gstate * gs, int converter)
787
0
{
788
0
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(gs->memory);
789
790
0
    libctx->core->scanconverter = converter;
791
792
0
    sanitize_fill_adjust(gs);
793
0
}
794
795
/* getscanconverter */
796
int
797
gs_getscanconverter(const gs_memory_t * mem)
798
6.62M
{
799
6.62M
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
800
801
6.62M
    return libctx->core->scanconverter;
802
6.62M
}
803
804
/* setrenderingintent
805
 *
806
 *  Use ICC numbers from Table 18 (section 6.1.11) rather than the PDF order
807
 *  to reduce re-coding and confusion.
808
 *    Perceptual            0
809
 *    Relative Colorimetric 1
810
 *    Saturation            2
811
 *    AbsoluteColorimetric  3
812
 */
813
int
814
88.3k
gs_setrenderingintent(gs_gstate *pgs, int ri) {
815
88.3k
    if (ri < 0 || ri > 3)
816
1
        return_error(gs_error_rangecheck);
817
88.3k
    pgs->renderingintent = ri;
818
88.3k
    return 0;
819
88.3k
}
820
821
/* currentrenderingintent */
822
int
823
gs_currentrenderingintent(const gs_gstate * pgs)
824
52.3k
{
825
52.3k
    return pgs->renderingintent;
826
52.3k
}
827
828
int
829
18
gs_setblackptcomp(gs_gstate *pgs, bool bkpt) {
830
18
    pgs->blackptcomp = bkpt;
831
18
    return 0;
832
18
}
833
834
/* currentrenderingintent */
835
bool
836
gs_currentblackptcomp(const gs_gstate * pgs)
837
2
{
838
2
    return pgs->blackptcomp;
839
2
}
840
841
/*
842
 * Reset most of the graphics state.
843
 */
844
int
845
gs_initgraphics(gs_gstate * pgs)
846
637k
{
847
637k
    int code;
848
637k
    const gs_gstate gstate_initial = {
849
637k
            gs_gstate_initial(1.0)
850
637k
        };
851
637k
    gs_matrix m;
852
637k
    gs_make_identity(&m);
853
854
637k
    gs_initmatrix(pgs);
855
637k
    if ((code = gs_newpath(pgs)) < 0 ||
856
637k
        (code = gs_initclip(pgs)) < 0 ||
857
637k
        (code = gs_setlinewidth(pgs, 1.0)) < 0 ||
858
637k
        (code = gs_setlinestartcap(pgs, gstate_initial.line_params.start_cap)) < 0 ||
859
637k
        (code = gs_setlineendcap(pgs, gstate_initial.line_params.end_cap)) < 0 ||
860
637k
        (code = gs_setlinedashcap(pgs, gstate_initial.line_params.dash_cap)) < 0 ||
861
637k
        (code = gs_setlinejoin(pgs, gstate_initial.line_params.join)) < 0 ||
862
637k
        (code = gs_setcurvejoin(pgs, gstate_initial.line_params.curve_join)) < 0 ||
863
637k
        (code = gs_setdash(pgs, (float *)0, 0, 0.0)) < 0 ||
864
637k
        (gs_setdashadapt(pgs, false),
865
637k
         (code = gs_setdotlength(pgs, 0.0, false))) < 0 ||
866
637k
        (code = gs_setdotorientation(pgs)) < 0 ||
867
637k
        (code = gs_setmiterlimit(pgs, gstate_initial.line_params.miter_limit)) < 0
868
637k
        )
869
0
        return code;
870
637k
    gs_init_rop(pgs);
871
    /* Initialize things so that gx_remap_color won't crash. */
872
637k
    if (pgs->icc_manager->default_gray == 0x00) {
873
89.2k
        gs_color_space  *pcs1, *pcs2;
874
875
89.2k
        pcs1 = gs_cspace_new_DeviceGray(pgs->memory);
876
89.2k
        if (pcs1 == NULL)
877
0
            return_error(gs_error_unknownerror);
878
879
89.2k
        if (pgs->color[0].color_space != NULL) {
880
0
            gs_setcolorspace(pgs, pcs1);
881
0
            rc_decrement_cs(pcs1, "gs_initgraphics");
882
89.2k
        } else {
883
89.2k
            pgs->color[0].color_space = pcs1;
884
89.2k
            gs_setcolorspace(pgs, pcs1);
885
89.2k
        }
886
89.2k
        code = gx_set_dev_color(pgs);
887
89.2k
        if (code < 0)
888
0
            return code;
889
890
89.2k
        gs_swapcolors_quick(pgs); /* To color 1 */
891
892
89.2k
        pcs2 = gs_cspace_new_DeviceGray(pgs->memory);
893
89.2k
        if (pcs2 == NULL)
894
0
            return_error(gs_error_unknownerror);
895
896
89.2k
        if (pgs->color[0].color_space != NULL) {
897
0
            gs_setcolorspace(pgs, pcs2);
898
0
            rc_decrement_cs(pcs2, "gs_initgraphics");
899
89.2k
        } else {
900
89.2k
            pgs->color[0].color_space = pcs2;
901
89.2k
            gs_setcolorspace(pgs, pcs2);
902
89.2k
        }
903
89.2k
        code = gx_set_dev_color(pgs);
904
905
89.2k
        gs_swapcolors_quick(pgs); /* To color 0 */
906
907
89.2k
        if (code < 0)
908
0
            return code;
909
910
548k
    } else {
911
548k
        gs_color_space  *pcs1, *pcs2;
912
913
548k
        pcs1 = gs_cspace_new_ICC(pgs->memory, pgs, 1);
914
548k
        if (pcs1 == NULL)
915
0
            return_error(gs_error_unknownerror);
916
917
548k
        if (pgs->color[0].color_space != NULL) {
918
507k
            gs_setcolorspace(pgs, pcs1);
919
507k
            rc_decrement_cs(pcs1, "gs_initgraphics");
920
507k
        } else {
921
40.8k
            pgs->color[0].color_space = pcs1;
922
40.8k
            gs_setcolorspace(pgs, pcs1);
923
40.8k
        }
924
548k
        code = gx_set_dev_color(pgs);
925
548k
        if (code < 0)
926
0
            return code;
927
928
548k
        gs_swapcolors_quick(pgs); /* To color 1 */
929
548k
        pcs2 = gs_cspace_new_ICC(pgs->memory, pgs, 1);
930
548k
        if (pcs2 == NULL)
931
0
            return_error(gs_error_unknownerror);
932
933
548k
        if (pgs->color[0].color_space != NULL) {
934
507k
            gs_setcolorspace(pgs, pcs2);
935
507k
            rc_decrement_cs(pcs2, "gs_initgraphics");
936
507k
        } else {
937
40.8k
            pgs->color[0].color_space = pcs2;
938
40.8k
            gs_setcolorspace(pgs, pcs2);
939
40.8k
        }
940
548k
        code = gx_set_dev_color(pgs);
941
942
548k
        gs_swapcolors_quick(pgs); /* To color 0 */
943
944
548k
        if (code < 0)
945
0
            return code;
946
548k
    }
947
637k
    pgs->in_cachedevice = 0;
948
949
637k
    code = gs_settextspacing(pgs, (double)0.0);
950
637k
    if (code < 0)
951
0
        goto exit;
952
637k
    code = gs_settextleading(pgs, (double)0.0);
953
637k
    if (code < 0)
954
0
        goto exit;
955
956
637k
    gs_settextrenderingmode(pgs, 0);
957
958
637k
    code = gs_setwordspacing(pgs, (double)0.0);
959
637k
    if (code < 0)
960
0
        goto exit;
961
637k
    code = gs_settexthscaling(pgs, (double)100.0);
962
637k
    if (code < 0)
963
0
        goto exit;
964
965
637k
    gs_setaccuratecurves(pgs, true);
966
967
637k
    code = gs_setstrokeconstantalpha(pgs, 1.0);
968
637k
    if (code < 0)
969
0
        goto exit;
970
637k
    code = gs_setfillconstantalpha(pgs, 1.0);
971
637k
    if (code < 0)
972
0
        goto exit;
973
637k
    code = gs_setalphaisshape(pgs, 0);
974
637k
    if (code < 0)
975
0
        goto exit;
976
637k
    code = gs_setblendmode(pgs, BLEND_MODE_Compatible);
977
637k
    if (code < 0)
978
0
        goto exit;
979
637k
    code = gs_settextknockout(pgs, true);
980
637k
    if (code < 0)
981
0
        goto exit;
982
637k
    code = gs_setsmoothness(pgs, 0.02); /* Match gs code */
983
637k
    if (code < 0)
984
0
        goto exit;
985
986
637k
    code = gs_settextmatrix(pgs, &m);
987
637k
    if (code < 0)
988
0
        goto exit;
989
990
637k
    code = gs_settextlinematrix(pgs, &m);
991
637k
    if (code < 0)
992
0
        goto exit;
993
637k
exit:
994
637k
    return code;
995
637k
}
996
997
/* setfilladjust */
998
int
999
gs_setfilladjust(gs_gstate * pgs, double adjust_x, double adjust_y)
1000
219k
{
1001
219k
#define CLAMP_TO_HALF(v)\
1002
438k
    ((v) <= 0 ? fixed_0 : (v) >= 0.5 ? fixed_half : float2fixed(v));
1003
1004
219k
    pgs->fill_adjust.x = CLAMP_TO_HALF(adjust_x);
1005
219k
    pgs->fill_adjust.y = CLAMP_TO_HALF(adjust_y);
1006
1007
219k
    sanitize_fill_adjust(pgs);
1008
1009
219k
    return 0;
1010
219k
#undef CLAMP_TO_HALF
1011
219k
}
1012
1013
/* currentfilladjust */
1014
int
1015
gs_currentfilladjust(const gs_gstate * pgs, gs_point * adjust)
1016
55.9k
{
1017
55.9k
    adjust->x = fixed2float(pgs->fill_adjust.x);
1018
55.9k
    adjust->y = fixed2float(pgs->fill_adjust.y);
1019
55.9k
    return 0;
1020
55.9k
}
1021
1022
/* setlimitclamp */
1023
void
1024
gs_setlimitclamp(gs_gstate * pgs, bool clamp)
1025
260k
{
1026
260k
    pgs->clamp_coordinates = clamp;
1027
260k
}
1028
1029
/* currentlimitclamp */
1030
bool
1031
gs_currentlimitclamp(const gs_gstate * pgs)
1032
0
{
1033
0
    return pgs->clamp_coordinates;
1034
0
}
1035
1036
/* settextrenderingmode */
1037
void
1038
gs_settextrenderingmode(gs_gstate * pgs, uint trm)
1039
808k
{
1040
808k
    pgs->text_rendering_mode = trm;
1041
808k
}
1042
1043
/* currenttextrenderingmode */
1044
uint
1045
gs_currenttextrenderingmode(const gs_gstate * pgs)
1046
9.56M
{
1047
9.56M
    return pgs->text_rendering_mode;
1048
9.56M
}
1049
1050
double
1051
gs_currenttextspacing(const gs_gstate *pgs)
1052
6.58M
{
1053
6.58M
    return pgs->textspacing;
1054
6.58M
}
1055
1056
int
1057
gs_settextspacing(gs_gstate *pgs, double Tc)
1058
1.15M
{
1059
1.15M
    int code = 0;
1060
1.15M
    gs_fixed_point dxy;
1061
1062
1.15M
    code = gs_distance_transform2fixed(&pgs->ctm, Tc, 1, &dxy);
1063
1.15M
    if (code < 0)
1064
2.99k
        return code;
1065
1066
1.15M
    pgs->textspacing = (float)Tc;
1067
1.15M
    return 0;
1068
1.15M
}
1069
1070
double
1071
gs_currenttextleading(const gs_gstate *pgs)
1072
0
{
1073
0
    return pgs->textleading;
1074
0
}
1075
1076
int
1077
gs_settextleading(gs_gstate *pgs, double TL)
1078
939k
{
1079
939k
    pgs->textleading = (float)TL;
1080
939k
    return 0;
1081
939k
}
1082
1083
double
1084
gs_currenttextrise(const gs_gstate *pgs)
1085
0
{
1086
0
    return pgs->textrise;
1087
0
}
1088
1089
int
1090
gs_settextrise(gs_gstate *pgs, double Ts)
1091
1.03k
{
1092
1.03k
    pgs->textrise = (float)Ts;
1093
1.03k
    return 0;
1094
1.03k
}
1095
1096
double
1097
gs_currentwordspacing(const gs_gstate *pgs)
1098
6.58M
{
1099
6.58M
    return pgs->wordspacing;
1100
6.58M
}
1101
1102
int
1103
gs_setwordspacing(gs_gstate *pgs, double Tw)
1104
761k
{
1105
761k
    pgs->wordspacing = (float)Tw;
1106
761k
    return 0;
1107
761k
}
1108
1109
int
1110
gs_settexthscaling(gs_gstate *pgs, double Tz)
1111
683k
{
1112
683k
    pgs->texthscaling = (float)Tz;
1113
683k
    return 0;
1114
683k
}
1115
1116
double
1117
gs_currenttexthscaling(const gs_gstate *pgs)
1118
0
{
1119
0
    return pgs->texthscaling;
1120
0
}
1121
1122
int
1123
gs_setPDFfontsize(gs_gstate *pgs, double Tf)
1124
492k
{
1125
492k
    pgs->PDFfontsize = (float)Tf;
1126
492k
    return 0;
1127
492k
}
1128
1129
double
1130
gs_currentPDFfontsize(const gs_gstate *pgs)
1131
0
{
1132
0
    return pgs->PDFfontsize;
1133
0
}
1134
1135
int
1136
gs_settextlinematrix(gs_gstate *pgs, gs_matrix *m)
1137
2.99M
{
1138
2.99M
    pgs->textlinematrix.xx = m->xx;
1139
2.99M
    pgs->textlinematrix.xy = m->xy;
1140
2.99M
    pgs->textlinematrix.yx = m->yx;
1141
2.99M
    pgs->textlinematrix.yy = m->yy;
1142
2.99M
    pgs->textlinematrix.tx = m->tx;
1143
2.99M
    pgs->textlinematrix.ty = m->ty;
1144
2.99M
    return 0;
1145
2.99M
}
1146
int
1147
gs_gettextlinematrix(gs_gstate *pgs, gs_matrix *m)
1148
0
{
1149
0
    m->xx = pgs->textlinematrix.xx;
1150
0
    m->xy = pgs->textlinematrix.xy;
1151
0
    m->yx = pgs->textlinematrix.yx;
1152
0
    m->yy = pgs->textlinematrix.yy;
1153
0
    m->tx = pgs->textlinematrix.tx;
1154
0
    m->ty = pgs->textlinematrix.ty;
1155
0
    return 0;
1156
0
}
1157
1158
int
1159
gs_settextmatrix(gs_gstate *pgs, gs_matrix *m)
1160
2.99M
{
1161
2.99M
    pgs->textmatrix.xx = m->xx;
1162
2.99M
    pgs->textmatrix.xy = m->xy;
1163
2.99M
    pgs->textmatrix.yx = m->yx;
1164
2.99M
    pgs->textmatrix.yy = m->yy;
1165
2.99M
    pgs->textmatrix.tx = m->tx;
1166
2.99M
    pgs->textmatrix.ty = m->ty;
1167
2.99M
    return 0;
1168
2.99M
}
1169
int
1170
gs_gettextmatrix(gs_gstate *pgs, gs_matrix *m)
1171
0
{
1172
0
    m->xx = pgs->textmatrix.xx;
1173
0
    m->xy = pgs->textmatrix.xy;
1174
0
    m->yx = pgs->textmatrix.yx;
1175
0
    m->yy = pgs->textmatrix.yy;
1176
0
    m->tx = pgs->textmatrix.tx;
1177
0
    m->ty = pgs->textmatrix.ty;
1178
0
    return 0;
1179
0
}
1180
1181
1182
/* sethpglpathmode */
1183
void
1184
gs_sethpglpathmode(gs_gstate * pgs, bool path)
1185
0
{
1186
0
    pgs->hpgl_path_mode = path;
1187
0
}
1188
1189
/* currenthpglpathmode */
1190
bool
1191
gs_currenthpglpathmode(const gs_gstate * pgs)
1192
0
{
1193
0
    return pgs->hpgl_path_mode;
1194
0
}
1195
1196
/* ------ Internal routines ------ */
1197
1198
/* Free the privately allocated parts of a gstate. */
1199
static void
1200
gstate_free_parts(gs_gstate * parts, gs_memory_t * mem, client_name_t cname)
1201
24.2M
{
1202
24.2M
    gs_free_object(mem, parts->color[1].dev_color, cname);
1203
24.2M
    gs_free_object(mem, parts->color[1].ccolor, cname);
1204
24.2M
    gs_free_object(mem, parts->color[0].dev_color, cname);
1205
24.2M
    gs_free_object(mem, parts->color[0].ccolor, cname);
1206
24.2M
    parts->color[1].dev_color = 0;
1207
24.2M
    parts->color[1].ccolor = 0;
1208
24.2M
    parts->color[0].dev_color = 0;
1209
24.2M
    parts->color[0].ccolor = 0;
1210
24.2M
    if (!parts->effective_clip_shared && parts->effective_clip_path) {
1211
0
        gx_cpath_free(parts->effective_clip_path, cname);
1212
0
        parts->effective_clip_path = 0;
1213
0
    }
1214
24.2M
    gx_cpath_free(parts->clip_path, cname);
1215
24.2M
    parts->clip_path = 0;
1216
24.2M
    if (parts->path) {
1217
12.2M
        gx_path_free(parts->path, cname);
1218
12.2M
        parts->path = 0;
1219
12.2M
    }
1220
24.2M
}
1221
1222
static inline void
1223
gstate_parts_init_dev_color(gx_device_color *dc)
1224
24.4M
{
1225
24.4M
    gx_device_color_type dct = dc->type;
1226
24.4M
    gs_graphics_type_tag_t gtt = dc->tag;
1227
24.4M
    memset(dc, 0x00, sizeof(gx_device_color));
1228
24.4M
    dc->type = dct;
1229
24.4M
    dc->tag = gtt;
1230
24.4M
}
1231
1232
/* Allocate the privately allocated parts of a gstate. */
1233
static int
1234
gstate_alloc_parts(gs_gstate * parts, const gs_gstate * shared,
1235
                   gs_memory_t * mem, client_name_t cname)
1236
12.2M
{
1237
12.2M
    gs_memory_t *path_mem = gstate_path_memory(mem);
1238
1239
12.2M
    parts->path =
1240
12.2M
        (shared ?
1241
12.0M
         gx_path_alloc_shared(shared->path, path_mem,
1242
12.0M
                              "gstate_alloc_parts(path)") :
1243
12.2M
         gx_path_alloc(path_mem, "gstate_alloc_parts(path)"));
1244
12.2M
    parts->clip_path =
1245
12.2M
        (shared ?
1246
12.0M
         gx_cpath_alloc_shared(shared->clip_path, mem,
1247
12.0M
                               "gstate_alloc_parts(clip_path)") :
1248
12.2M
         gx_cpath_alloc(mem, "gstate_alloc_parts(clip_path)"));
1249
12.2M
    if (!shared || shared->effective_clip_shared) {
1250
12.2M
        parts->effective_clip_path = parts->clip_path;
1251
12.2M
        parts->effective_clip_shared = true;
1252
12.2M
    } else {
1253
0
        parts->effective_clip_path =
1254
0
            gx_cpath_alloc_shared(shared->effective_clip_path, mem,
1255
0
                                  "gstate_alloc_parts(effective_clip_path)");
1256
0
        parts->effective_clip_shared = false;
1257
0
    }
1258
12.2M
    parts->color[0].color_space = NULL;
1259
12.2M
    parts->color[1].color_space = NULL;
1260
12.2M
    parts->color[0].ccolor =
1261
12.2M
        gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
1262
12.2M
    parts->color[1].ccolor =
1263
12.2M
        gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
1264
12.2M
    parts->color[0].dev_color =
1265
12.2M
        gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
1266
12.2M
    parts->color[1].dev_color =
1267
12.2M
        gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
1268
12.2M
    if (parts->path == 0 || parts->clip_path == 0 ||
1269
12.2M
        parts->effective_clip_path == 0 ||
1270
12.2M
        parts->color[0].ccolor == 0 || parts->color[0].dev_color == 0 ||
1271
12.2M
        parts->color[1].ccolor == 0 || parts->color[1].dev_color == 0
1272
12.2M
        ) {
1273
203
        gstate_free_parts(parts, mem, cname);
1274
203
        return_error(gs_error_VMerror);
1275
203
    }
1276
12.2M
    gstate_parts_init_dev_color(parts->color[0].dev_color);
1277
12.2M
    gstate_parts_init_dev_color(parts->color[1].dev_color);
1278
12.2M
    return 0;
1279
12.2M
}
1280
1281
/*
1282
 * Allocate a gstate and its contents.
1283
 * If pfrom is not NULL, the path, clip_path, and (if distinct from both
1284
 * clip_path and view_clip) effective_clip_path share the segments of
1285
 * pfrom's corresponding path(s).
1286
 */
1287
static gs_gstate *
1288
gstate_alloc(gs_memory_t * mem, client_name_t cname, const gs_gstate * pfrom)
1289
12.2M
{
1290
12.2M
    gs_gstate *pgs =
1291
12.2M
        gs_alloc_struct(mem, gs_gstate, &st_gs_gstate, cname);
1292
1293
12.2M
    if (pgs == NULL)
1294
26
        return NULL;
1295
12.2M
    memset(pgs, 0x00, sizeof(gs_gstate));
1296
12.2M
    if (gstate_alloc_parts(pgs, pfrom, mem, cname) < 0) {
1297
203
        gs_free_object(mem, pgs, cname);
1298
203
        return NULL;
1299
203
    }
1300
12.2M
    pgs->memory = mem;
1301
12.2M
    return pgs;
1302
12.2M
}
1303
1304
/* Copy the dash pattern from one gstate to another. */
1305
static int
1306
gstate_copy_dash(gs_memory_t *mem, gx_dash_params *dash , const gs_gstate * pfrom)
1307
41.5k
{
1308
41.5k
    return gx_set_dash(dash, pfrom->line_params.dash.pattern,
1309
41.5k
                      pfrom->line_params.dash.pattern_size,
1310
41.5k
                      pfrom->line_params.dash.offset, mem);
1311
41.5k
}
1312
1313
typedef struct {
1314
    gs_gstate_parts  parts;
1315
    gx_dash_params   dash;
1316
} gs_gstate_clone_data;
1317
1318
static gs_gstate *
1319
gstate_clone_core(const gs_gstate               *pfrom,
1320
                        gs_memory_t             *mem,
1321
                        client_name_t            cname,
1322
                        gs_gstate_clone_data    *clone_data,
1323
                        gs_gstate_copy_reason_t  reason)
1324
12.0M
{
1325
12.0M
    gs_gstate *pgs = gstate_alloc(mem, cname, pfrom);
1326
12.0M
    void *pdata = NULL;
1327
1328
12.0M
    if (pgs == NULL)
1329
229
        return NULL;
1330
12.0M
    if (pfrom->client_data != NULL) {
1331
12.0M
        pdata = (*pfrom->client_procs.alloc) (mem);
1332
1333
12.0M
        if (pdata == NULL ||
1334
12.0M
            gstate_copy_client_data(pfrom, pdata, pfrom->client_data,
1335
12.0M
                                    reason) < 0)
1336
0
            goto failEarly;
1337
12.0M
    }
1338
    /* Copy the dash and dash pattern if necessary. */
1339
12.0M
    clone_data->dash = gs_currentlineparams_inline(pfrom)->dash;
1340
12.0M
    if (clone_data->dash.pattern) {
1341
41.4k
        int code;
1342
1343
41.4k
        clone_data->dash.pattern = NULL; /* Ensures a fresh allocation */
1344
41.4k
        code = gstate_copy_dash(mem, &clone_data->dash, pfrom);
1345
41.4k
        if (code < 0)
1346
0
            goto fail;
1347
41.4k
    }
1348
    /* Some records within pgs are allocated. We copy pfrom into pgs
1349
     * wholesale (to avoid problems with the structure being updated and
1350
     * us having to keep it in sync), so we copy those allocated regions
1351
     * out first. The caller of this routine will then put them back
1352
     * into either pgs or pfrom as appropriate. */
1353
12.0M
    GSTATE_ASSIGN_PARTS(&clone_data->parts, pgs);
1354
12.0M
    *pgs = *pfrom;
1355
12.0M
    pgs->client_data = pdata;
1356
1357
12.0M
    gs_gstate_copied(pgs);
1358
    /* Don't do anything to clip_stack. */
1359
1360
12.0M
    rc_increment(pgs->device);
1361
12.0M
    *clone_data->parts.color[0].ccolor    = *pgs->color[0].ccolor;
1362
12.0M
    *clone_data->parts.color[0].dev_color = *pgs->color[0].dev_color;
1363
12.0M
    *clone_data->parts.color[1].ccolor    = *pgs->color[1].ccolor;
1364
12.0M
    *clone_data->parts.color[1].dev_color = *pgs->color[1].dev_color;
1365
12.0M
    cs_adjust_counts_icc(pgs, 1);
1366
12.0M
    cs_adjust_swappedcounts_icc(pgs, 1);
1367
1368
12.0M
    return pgs;
1369
1370
0
  fail:
1371
0
    gs_free_object(mem, clone_data->dash.pattern, cname);
1372
0
    if (pdata != NULL)
1373
0
        (*pfrom->client_procs.free) (pdata, mem, pgs);
1374
0
  failEarly:
1375
0
    gstate_free_parts(pgs, mem, cname);
1376
0
    gs_free_object(mem, pgs, cname);
1377
1378
0
    return NULL;
1379
0
}
1380
1381
1382
/* Clone an existing graphics state for use in gsave. The clone refers
1383
 * to the old contents, and the old state refers to the new contents. */
1384
/* Return NULL if the allocation fails. */
1385
static gs_gstate *
1386
gstate_clone_for_gsave(gs_gstate     *pfrom,
1387
                       client_name_t  cname)
1388
11.3M
{
1389
11.3M
    gs_gstate_clone_data clone_data;
1390
11.3M
    gs_gstate *pgs = gstate_clone_core(pfrom, pfrom->memory, cname,
1391
11.3M
                                       &clone_data, copy_for_gsave);
1392
1393
11.3M
    if (pgs == NULL)
1394
229
        return NULL;
1395
1396
    /* Newly allocated parts go back into pfrom, not pgs! */
1397
11.3M
    GSTATE_ASSIGN_PARTS(pfrom, &clone_data.parts);
1398
11.3M
    gs_currentlineparams_inline(pfrom)->dash = clone_data.dash;
1399
1400
11.3M
    return pgs;
1401
11.3M
}
1402
1403
/* Clone an existing graphics state. The view_clip is not copied. */
1404
/* Return NULL if the allocation fails. */
1405
static gs_gstate *
1406
gstate_clone_for_gstate(const gs_gstate     *pfrom,
1407
                              gs_memory_t   *mem,
1408
                              client_name_t  cname)
1409
761k
{
1410
761k
    gs_gstate_clone_data clone_data;
1411
761k
    gs_gstate *pgs = gstate_clone_core(pfrom, mem, cname, &clone_data,
1412
761k
                                       copy_for_gstate);
1413
1414
761k
    if (pgs == NULL)
1415
0
        return NULL;
1416
761k
    GSTATE_ASSIGN_PARTS(pgs, &clone_data.parts);
1417
761k
    pgs->view_clip = NULL;
1418
761k
    gs_currentlineparams_inline(pgs)->dash = clone_data.dash;
1419
761k
    pgs->memory = mem;
1420
1421
761k
    return pgs;
1422
761k
}
1423
1424
/* Adjust reference counters for the whole clip stack */
1425
/* accessible from the given point */
1426
static void
1427
clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t cname)
1428
25.0M
{
1429
25.0M
    gx_clip_stack_t *p = cs;
1430
1431
25.0M
    while(p) {
1432
0
        gx_clip_stack_t *q = p;
1433
0
        p = p->next;
1434
0
        rc_adjust(q, delta, cname);
1435
0
    }
1436
25.0M
}
1437
1438
/*
1439
 * Finalization for graphics states. This is where we handle RC for those
1440
 * elements.
1441
 */
1442
void
1443
gs_gstate_finalize(const gs_memory_t *cmem,void *vptr)
1444
12.2M
{
1445
12.2M
    gs_gstate *pgs = (gs_gstate *)vptr;
1446
12.2M
    (void)cmem; /* unused */
1447
1448
12.2M
    if (cmem == NULL)
1449
0
        return;     /* place for breakpoint */
1450
12.2M
    gstate_free_contents(pgs);
1451
12.2M
}
1452
1453
/* Release the composite parts of a graphics state, */
1454
/* but not the state itself. */
1455
static void
1456
gstate_free_contents(gs_gstate * pgs)
1457
24.2M
{
1458
24.2M
    gs_memory_t *mem = pgs->memory;
1459
24.2M
    const char *const cname = "gstate_free_contents";
1460
1461
24.2M
    rc_decrement(pgs->device, cname);
1462
24.2M
    pgs->device = 0;
1463
24.2M
    clip_stack_rc_adjust(pgs->clip_stack, -1, cname);
1464
24.2M
    pgs->clip_stack = 0;
1465
24.2M
    if (pgs->view_clip != NULL && pgs->level == 0) {
1466
130k
        gx_cpath_free(pgs->view_clip, cname);
1467
130k
        pgs->view_clip = NULL;
1468
130k
    }
1469
24.2M
    if (pgs->client_data != 0)
1470
12.2M
        (*pgs->client_procs.free) (pgs->client_data, mem, pgs);
1471
24.2M
    pgs->client_data = 0;
1472
24.2M
    cs_adjust_counts_icc(pgs, -1);
1473
24.2M
    cs_adjust_swappedcounts_icc(pgs, -1);
1474
24.2M
    pgs->color[0].color_space = 0;
1475
24.2M
    pgs->color[1].color_space = 0;
1476
24.2M
    gs_free_object(mem, pgs->line_params.dash.pattern, cname);
1477
24.2M
    pgs->line_params.dash.pattern = 0;
1478
24.2M
    gstate_free_parts(pgs, mem, cname);     /* this also clears pointers to freed elements */
1479
24.2M
    gs_gstate_release(pgs);
1480
24.2M
}
1481
1482
/* Copy one gstate to another. */
1483
static int
1484
gstate_copy(gs_gstate * pto, const gs_gstate * pfrom,
1485
            gs_gstate_copy_reason_t reason, client_name_t cname)
1486
18.1k
{
1487
18.1k
    gs_gstate_parts parts;
1488
1489
18.1k
    GSTATE_ASSIGN_PARTS(&parts, pto);
1490
    /* Copy the dash pattern if necessary. */
1491
18.1k
    if (pfrom->line_params.dash.pattern || pto->line_params.dash.pattern) {
1492
91
        int code = gstate_copy_dash(pto->memory,
1493
91
                             &(gs_currentlineparams_inline(pto)->dash), pfrom);
1494
1495
91
        if (code < 0)
1496
0
            return code;
1497
91
    }
1498
    /*
1499
     * It's OK to decrement the counts before incrementing them,
1500
     * because anything that is going to survive has a count of
1501
     * at least 2 (pto and somewhere else) initially.
1502
     * Handle references from contents.
1503
     */
1504
18.1k
    cs_adjust_counts_icc(pto, -1);
1505
18.1k
    cs_adjust_swappedcounts_icc(pto, -1);
1506
18.1k
    gx_path_assign_preserve(pto->path, pfrom->path);
1507
18.1k
    gx_cpath_assign_preserve(pto->clip_path, pfrom->clip_path);
1508
    /*
1509
     * effective_clip_shared will be copied, but we need to do the
1510
     * right thing with effective_clip_path.
1511
     */
1512
18.1k
    if (pfrom->effective_clip_shared) {
1513
        /*
1514
         * pfrom->effective_clip_path is either pfrom->view_clip or
1515
         * pfrom->clip_path.
1516
         */
1517
18.1k
        parts.effective_clip_path =
1518
18.1k
            (pfrom->effective_clip_path == pfrom->view_clip ?
1519
18.1k
             pto->view_clip : parts.clip_path);
1520
18.1k
    } else
1521
0
        gx_cpath_assign_preserve(pto->effective_clip_path,
1522
0
                                 pfrom->effective_clip_path);
1523
18.1k
    *parts.color[0].ccolor    = *pfrom->color[0].ccolor;
1524
18.1k
    *parts.color[0].dev_color = *pfrom->color[0].dev_color;
1525
18.1k
    *parts.color[1].ccolor    = *pfrom->color[1].ccolor;
1526
18.1k
    *parts.color[1].dev_color = *pfrom->color[1].dev_color;
1527
    /* Handle references from gstate object. */
1528
18.1k
    rc_pre_assign(pto->device, pfrom->device, cname);
1529
18.1k
    if (pto->clip_stack != pfrom->clip_stack) {
1530
0
        clip_stack_rc_adjust(pfrom->clip_stack, 1, cname);
1531
0
        clip_stack_rc_adjust(pto->clip_stack, -1, cname);
1532
0
    }
1533
18.1k
    {
1534
18.1k
        struct gx_pattern_cache_s *pcache = pto->pattern_cache;
1535
18.1k
        void *pdata = pto->client_data;
1536
18.1k
        gs_memory_t *mem = pto->memory;
1537
18.1k
        gs_gstate *saved = pto->saved;
1538
18.1k
        float *pattern = pto->line_params.dash.pattern;
1539
1540
18.1k
        gs_gstate_pre_assign(pto, (const gs_gstate *)pfrom);
1541
18.1k
        *pto = *pfrom;
1542
18.1k
        pto->client_data = pdata;
1543
18.1k
        pto->memory = mem;
1544
18.1k
        pto->saved = saved;
1545
18.1k
        pto->line_params.dash.pattern = pattern;
1546
18.1k
        if (pto->pattern_cache == 0)
1547
0
            pto->pattern_cache = pcache;
1548
18.1k
        if (pfrom->client_data != 0) {
1549
            /* We need to break 'const' here. */
1550
17.6k
            gstate_copy_client_data((gs_gstate *) pfrom, pdata,
1551
17.6k
                                    pfrom->client_data, reason);
1552
17.6k
        }
1553
18.1k
    }
1554
18.1k
    GSTATE_ASSIGN_PARTS(pto, &parts);
1555
18.1k
    cs_adjust_counts_icc(pto, 1);
1556
18.1k
    cs_adjust_swappedcounts_icc(pto, 1);
1557
18.1k
    pto->show_gstate =
1558
18.1k
        (pfrom->show_gstate == pfrom ? pto : 0);
1559
18.1k
    return 0;
1560
18.1k
}
1561
1562
/* Accessories. */
1563
gs_id gx_get_clip_path_id(gs_gstate *pgs)
1564
3.87k
{
1565
3.87k
    return pgs->clip_path->id;
1566
3.87k
}
1567
1568
void gs_swapcolors_quick(const gs_gstate *cpgs)
1569
9.05M
{
1570
9.05M
    union {
1571
9.05M
        const gs_gstate *cpgs;
1572
9.05M
        gs_gstate *pgs;
1573
9.05M
    } const_breaker;
1574
9.05M
    gs_gstate *pgs;
1575
9.05M
    struct gx_cie_joint_caches_s *tmp_cie;
1576
9.05M
    gs_devicen_color_map          tmp_ccm;
1577
9.05M
    gs_client_color              *tmp_cc;
1578
9.05M
    int                           tmp;
1579
9.05M
    gx_device_color              *tmp_dc;
1580
9.05M
    gs_color_space               *tmp_cs;
1581
1582
    /* Break const just once, neatly, here rather than
1583
     * hackily in every caller. */
1584
9.05M
    const_breaker.cpgs = cpgs;
1585
9.05M
    pgs = const_breaker.pgs;
1586
1587
9.05M
    tmp_cc               = pgs->color[0].ccolor;
1588
9.05M
    pgs->color[0].ccolor = pgs->color[1].ccolor;
1589
9.05M
    pgs->color[1].ccolor = tmp_cc;
1590
1591
9.05M
    tmp_dc                  = pgs->color[0].dev_color;
1592
9.05M
    pgs->color[0].dev_color = pgs->color[1].dev_color;
1593
9.05M
    pgs->color[1].dev_color = tmp_dc;
1594
1595
9.05M
    tmp_cs                    = pgs->color[0].color_space;
1596
9.05M
    pgs->color[0].color_space = pgs->color[1].color_space;
1597
9.05M
    pgs->color[1].color_space = tmp_cs;
1598
1599
    /* Overprint and effective_op vary with stroke/fill and cs */
1600
9.05M
    tmp                         = pgs->color[0].effective_opm;
1601
9.05M
    pgs->color[0].effective_opm = pgs->color[1].effective_opm;
1602
9.05M
    pgs->color[1].effective_opm = tmp;
1603
1604
    /* Swap the bits of the gs_gstate that depend on the current color */
1605
9.05M
    tmp_cie                   = pgs->cie_joint_caches;
1606
9.05M
    pgs->cie_joint_caches     = pgs->cie_joint_caches_alt;
1607
9.05M
    pgs->cie_joint_caches_alt = tmp_cie;
1608
1609
9.05M
    tmp_ccm                      = pgs->color_component_map;
1610
9.05M
    pgs->color_component_map     = pgs->color_component_map_alt;
1611
9.05M
    pgs->color_component_map_alt = tmp_ccm;
1612
1613
9.05M
    pgs->is_fill_color = !(pgs->is_fill_color); /* used by overprint for fill_stroke */
1614
9.05M
}