Coverage Report

Created: 2026-07-24 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gsstate.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
/* 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
85.7M
  ((pto)->path = (pfrom)->path, (pto)->clip_path = (pfrom)->clip_path,\
155
85.7M
   (pto)->effective_clip_path = (pfrom)->effective_clip_path,\
156
85.7M
   (pto)->color[0].ccolor = (pfrom)->color[0].ccolor,\
157
85.7M
   (pto)->color[0].dev_color = (pfrom)->color[0].dev_color,\
158
85.7M
   (pto)->color[1].ccolor = (pfrom)->color[1].ccolor,\
159
85.7M
   (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
84.0M
{
169
84.0M
    return (pgs->client_procs.copy_for != 0 ?
170
7.61M
            (*pgs->client_procs.copy_for) (dto, dfrom, reason) :
171
84.0M
            (*pgs->client_procs.copy) (dto, dfrom));
172
84.0M
}
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
43.7M
{
186
43.7M
    return gs_memory_stable(mem);
187
43.7M
}
188
189
/* Allocate and initialize a graphics state. */
190
gs_gstate *
191
gs_gstate_alloc(gs_memory_t * mem)
192
444k
{
193
444k
    gs_gstate *pgs = gstate_alloc(mem, "gs_gstate_alloc", NULL);
194
444k
    gs_memory_t *path_mem = gstate_path_memory(mem);
195
444k
    int code;
196
197
444k
    if (pgs == 0)
198
0
        return 0;
199
444k
    GS_STATE_INIT_VALUES(pgs, 1.0);
200
    /* Need to set up at least enough to make gs_gstate_free happy */
201
444k
    pgs->saved = 0;
202
444k
    pgs->clip_stack = NULL;
203
444k
    pgs->view_clip = NULL;
204
444k
    pgs->font = NULL;
205
444k
    pgs->root_font = NULL;
206
444k
    pgs->show_gstate = NULL;
207
444k
    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
444k
    code = gs_gstate_initialize(pgs, mem);
215
444k
    if (code < 0)
216
0
        goto fail;
217
218
    /* Finish initializing the color rendering state. */
219
220
444k
    rc_alloc_struct_1(pgs->halftone, gs_halftone, &st_halftone, mem,
221
444k
                      goto fail, "gs_gstate_alloc(halftone)");
222
444k
    pgs->halftone->type = ht_type_none;
223
224
    /* Initialize other things not covered by initgraphics */
225
226
444k
    pgs->clip_stack = 0;
227
444k
    pgs->view_clip = gx_cpath_alloc(path_mem, "gs_gstate_alloc(view_clip)");
228
444k
    if (pgs->view_clip == NULL)
229
0
        goto fail;
230
444k
    pgs->view_clip->rule = 0;   /* no clipping */
231
444k
    pgs->effective_clip_id = pgs->clip_path->id;
232
444k
    pgs->effective_view_clip_id = gs_no_id;
233
444k
    pgs->in_cachedevice = 0;
234
444k
    pgs->device = 0;            /* setting device adjusts refcts */
235
444k
    code = gs_nulldevice(pgs);
236
444k
    if (code < 0)
237
0
        goto fail;
238
444k
    gs_setfillconstantalpha(pgs, 1.0);
239
444k
    gs_setstrokeconstantalpha(pgs, 1.0);
240
444k
    gs_setalphaisshape(pgs, false);
241
444k
    gs_settransfer(pgs, gs_identity_transfer);
242
444k
    gs_setflat(pgs, 1.0);
243
444k
    gs_setfilladjust(pgs, 0.3, 0.3);
244
444k
    gs_setlimitclamp(pgs, false);
245
444k
    gs_setstrokeadjust(pgs, true);
246
444k
    pgs->font = 0;              /* Not right, but acceptable until the */
247
    /* PostScript code does the first setfont. */
248
444k
    pgs->root_font = 0;         /* ditto */
249
444k
    pgs->in_charpath = (gs_char_path_mode) 0;
250
444k
    pgs->show_gstate = 0;
251
444k
    pgs->level = 0;
252
444k
    if (gs_initgraphics(pgs) >= 0)
253
444k
        return pgs;
254
    /* Something went very wrong. */
255
0
fail:
256
0
    gs_gstate_free(pgs);
257
0
    return 0;
258
444k
}
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
1.12M
{
266
1.12M
    pgs->client_data = pdata;
267
1.12M
    pgs->client_procs = *pprocs;
268
1.12M
    pgs->have_pattern_streams = client_has_pattern_streams;
269
1.12M
}
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
48.6M
{
276
48.6M
    return pgs->client_data;
277
48.6M
}
278
279
/* Free the chain of gstates.*/
280
void
281
gs_gstate_free_chain(gs_gstate * pgs)
282
135k
{
283
135k
   gs_gstate *saved = pgs, *tmp;
284
285
386k
   while(saved != 0) {
286
251k
       tmp = saved->saved;
287
251k
       gs_gstate_free(saved);
288
251k
       saved = tmp;
289
251k
   }
290
135k
}
291
292
/* Free a graphics state. */
293
void
294
gs_gstate_free(gs_gstate * pgs)
295
1.52M
{
296
1.52M
    if (pgs == NULL)
297
6.78k
        return;
298
1.51M
    gstate_free_contents(pgs);
299
1.51M
    gs_free_object(pgs->memory, pgs, "gs_gstate_free");
300
1.51M
}
301
302
/* Save the graphics state. */
303
int
304
gs_gsave(gs_gstate * pgs)
305
41.7M
{
306
41.7M
    gs_gstate *pnew = gstate_clone_for_gsave(pgs, "gs_gsave");
307
308
41.7M
    if (pnew == NULL)
309
4
        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
41.7M
    pgs->clip_stack = NULL;
319
41.7M
    pgs->saved = pnew;
320
41.7M
    if (pgs->show_gstate == pgs)
321
0
        pgs->show_gstate = pnew->show_gstate = pnew;
322
41.7M
    pgs->trans_flags.xstate_change = false;
323
41.7M
    pgs->level++;
324
41.7M
    if_debug2m('g', pgs->memory, "[g]gsave -> "PRI_INTPTR", level = %d\n",
325
41.7M
              (intptr_t)pnew, pgs->level);
326
41.7M
    return 0;
327
41.7M
}
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
1.08M
{
337
1.08M
    int code;
338
1.08M
    gx_clip_path *old_cpath = pgs->view_clip;
339
1.08M
    gx_clip_path *new_cpath;
340
341
1.08M
    if (old_cpath) {
342
1.08M
        new_cpath =
343
1.08M
            gx_cpath_alloc_shared(old_cpath, pgs->memory,
344
1.08M
                                  "gs_gsave_for_save(view_clip)");
345
1.08M
        if (new_cpath == 0)
346
0
            return_error(gs_error_VMerror);
347
1.08M
    } else {
348
0
        new_cpath = 0;
349
0
    }
350
1.08M
    code = gs_gsave(pgs);
351
1.08M
    if (code < 0)
352
0
        goto fail;
353
1.08M
    if (pgs->effective_clip_path == pgs->view_clip)
354
0
        pgs->effective_clip_path = new_cpath;
355
1.08M
    pgs->view_clip = new_cpath;
356
    /* Cut the stack so we can't grestore past here. */
357
1.08M
    *psaved = pgs->saved;
358
1.08M
    pgs->saved = 0;
359
360
1.08M
    code = gs_gsave(pgs);
361
1.08M
    if (code < 0) {
362
3
        pgs->saved = *psaved;
363
3
        *psaved = NULL;
364
3
        gs_grestore(pgs);
365
3
        return code;
366
3
    }
367
1.08M
    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
1.08M
}
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
41.4M
{
378
41.4M
    gs_gstate *saved = pgs->saved;
379
41.4M
    gs_gstate tmp_gstate;
380
41.4M
    void *pdata = pgs->client_data;
381
41.4M
    void *sdata;
382
383
41.4M
    if_debug2m('g', pgs->memory, "[g]grestore "PRI_INTPTR", level was %d\n",
384
41.4M
               (intptr_t)saved, pgs->level);
385
41.4M
    if (!saved)
386
35
        return 1;
387
41.4M
    sdata = saved->client_data;
388
41.4M
    if (saved->pattern_cache == 0)
389
3.66M
        saved->pattern_cache = pgs->pattern_cache;
390
    /* Swap back the client data pointers. */
391
41.4M
    pgs->client_data = sdata;
392
41.4M
    saved->client_data = pdata;
393
41.4M
    if (pdata != 0 && sdata != 0)
394
41.3M
        gstate_copy_client_data(pgs, pdata, sdata, copy_for_grestore);
395
41.4M
    gstate_free_contents(pgs);
396
41.4M
    tmp_gstate = *pgs;              /* temp after contents freed (with pointers zeroed) */
397
41.4M
    *pgs = *saved;
398
41.4M
    if (pgs->show_gstate == saved)
399
0
        pgs->show_gstate = pgs;
400
41.4M
    *saved = tmp_gstate;            /* restore "freed" state (pointers zeroed after contents freed) */
401
41.4M
    gs_free_object(pgs->memory, saved, "gs_grestore");
402
403
41.4M
    return 0;
404
41.4M
}
405
406
/* Restore the graphics state per PostScript semantics */
407
int
408
gs_grestore(gs_gstate * pgs)
409
41.2M
{
410
41.2M
    int code;
411
41.2M
    if (!pgs->saved)
412
0
        return gs_gsave(pgs);   /* shouldn't ever happen */
413
41.2M
    code = gs_grestore_only(pgs);
414
41.2M
    if (code < 0)
415
0
        return code;
416
417
    /* Wraparound: make sure there are always >= 1 saves on stack */
418
41.2M
    if (pgs->saved)
419
34.2M
        return 0;
420
6.99M
    return gs_gsave(pgs);
421
41.2M
}
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
1.08M
{
428
1.08M
    int code;
429
430
1.83M
    while (pgs->saved->saved) {
431
754k
        code = gs_grestore(pgs);
432
754k
        if (code < 0)
433
0
            return code;
434
754k
    }
435
    /* Make sure we don't leave dangling pointers in the caches. */
436
1.08M
    if (pgs->pattern_cache)
437
1.08M
        (*pgs->pattern_cache->free_all) (pgs->pattern_cache);
438
1.08M
    pgs->saved->saved = saved;
439
1.08M
    code = gs_grestore(pgs);
440
1.08M
    if (code < 0)
441
0
        return code;
442
1.08M
    if (pgs->view_clip) {
443
1.08M
        gx_cpath_free(pgs->view_clip, "gs_grestoreall_for_restore");
444
1.08M
        pgs->view_clip = 0;
445
1.08M
    }
446
1.08M
    return gs_grestore(pgs);
447
1.08M
}
448
449
/* Restore to the bottommost graphics state (at this save level). */
450
int
451
gs_grestoreall(gs_gstate * pgs)
452
390
{
453
390
    if (!pgs->saved)            /* shouldn't happen */
454
0
        return gs_gsave(pgs);
455
686
    while (pgs->saved->saved) {
456
296
        int code = gs_grestore(pgs);
457
458
296
        if (code < 0)
459
0
            return code;
460
296
    }
461
390
    return gs_grestore(pgs);
462
390
}
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
1.12M
{
468
1.12M
    gs_gstate *pnew;
469
470
1.12M
    pnew = gstate_clone_for_gstate(pgs, mem, "gs_gstate");
471
1.12M
    if (pnew == NULL)
472
0
        return NULL;
473
1.12M
    clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_gstate_copy");
474
1.12M
    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
1.12M
    pnew->show_gstate =
482
1.12M
        (pgs->show_gstate == pgs ? pnew : NULL);
483
1.12M
    return pnew;
484
1.12M
}
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
2
{
497
2
    int code =
498
2
        gstate_copy(pto, pgs, copy_for_currentgstate, "gs_currentgstate");
499
500
2
    if (code >= 0)
501
2
        pto->view_clip = 0;
502
2
    return code;
503
2
}
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
38.3k
{
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
38.3k
    gs_gstate *saved_show = pgs->show_gstate;
515
38.3k
    int level = pgs->level;
516
38.3k
    gx_clip_path *view_clip = pgs->view_clip;
517
38.3k
    int code;
518
519
38.3k
    pgs->view_clip = 0;         /* prevent refcount decrementing */
520
38.3k
    code = gstate_copy(pgs, pfrom, copy_for_setgstate, "gs_setgstate");
521
38.3k
    if (code < 0)
522
0
        return code;
523
38.3k
    pgs->level = level;
524
38.3k
    pgs->view_clip = view_clip;
525
38.3k
    pgs->show_gstate =
526
38.3k
        (pgs->show_gstate == pfrom ? pgs : saved_show);
527
38.3k
    return 0;
528
38.3k
}
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
487k
{
536
487k
    return pgs->memory;
537
487k
}
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
12.4M
{
544
12.4M
    return pgs->saved;
545
12.4M
}
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
4
{
563
4
    gs_memory_t *memory = pgs->memory;
564
565
4
    pgs->memory = mem;
566
4
    return memory;
567
4
}
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
1.04M
{
580
1.04M
    gs_composite_t *    pct = 0;
581
1.04M
    int                 code;
582
1.04M
    gx_device *         dev = pgs->device;
583
1.04M
    gx_device *         ovptdev;
584
585
1.04M
    code = gs_create_overprint(&pct, pparams, pgs->memory);
586
1.04M
    if (code >= 0) {
587
1.04M
        code = dev_proc(dev, composite)( dev,
588
1.04M
                                                   &ovptdev,
589
1.04M
                                                   pct,
590
1.04M
                                                   pgs,
591
1.04M
                                                   pgs->memory,
592
1.04M
                                                   NULL);
593
1.04M
        if (code >= 0 || code == gs_error_handled){
594
1.04M
            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
1.04M
            code = 0;
600
1.04M
        }
601
1.04M
    }
602
1.04M
    if (pct != 0)
603
1.04M
        gs_free_object(pgs->memory, pct, "gs_gstate_update_overprint");
604
605
    /* the following hack handles devices that don't support compositors */
606
1.04M
    if (code == gs_error_unknownerror && !pparams->retain_any_comps)
607
0
        code = 0;
608
1.04M
    return code;
609
1.04M
}
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
523k
{
630
523k
    const gs_color_space *  pcs = gs_currentcolorspace_inline(pgs);
631
523k
    const gs_client_color * pcc = gs_currentcolor_inline(pgs);
632
523k
    int                     code = 0;
633
634
523k
    if (cs_num_components(pcs) < 0 && pcc->pattern != 0)
635
0
        code = pcc->pattern->type->procs.set_color(pcc, pgs);
636
523k
    else {
637
523k
        gx_device* dev = pgs->device;
638
523k
        cmm_dev_profile_t* dev_profile;
639
523k
        gs_color_space_index pcs_index = gs_color_space_get_index(pcs);
640
641
523k
        dev_proc(dev, get_profile)(dev, &dev_profile);
642
523k
        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
523k
        if (dev_proc(dev, dev_spec_op)(dev, gxdso_pdf14_sep_device, NULL, 0) > 0 &&
650
167k
            (dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE)) {
651
167k
            if (pcs_index == gs_color_space_index_Separation) {
652
8.04k
                if (!(pcs->params.separation.color_type == SEP_MIX ||
653
0
                      pcs->params.separation.color_type == SEP_ENUM)) {
654
                    /* Sep color is not a spot color.  We can't do OP and trans */
655
0
                    return code;
656
0
                }
657
159k
            } else if (pcs_index == gs_color_space_index_DeviceN) {
658
0
                if (pcs->params.device_n.color_type != SEP_PURE_SPOT) {
659
                    /* DeviceN has process colors  We can't do OP and trans. */
660
0
                    return code;
661
0
                }
662
0
            }
663
167k
        }
664
665
        /* If we have a CIE-based space, use the ICC equivalent space */
666
523k
        if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent != NULL)
667
0
            pcs = pcs->icc_equivalent;
668
669
        /* The spaces that do not allow opm (e.g. ones that are not ICC or DeviceCMYK)
670
           will blow away any true setting later. But we have to be prepared
671
           in case this is a CMYK ICC space for example. Hence we set effective mode
672
           to mode here (Bug 698721)*/
673
523k
        pgs->color[0].effective_opm = pgs->overprint_mode;
674
675
523k
        if_debug2m(gs_debug_flag_overprint, pgs->memory,
676
523k
            "[overprint] gs_do_set_overprint. Preset effective mode. pgs->color[0].effective_opm = %d pgs->color[1].effective_opm = %d\n",
677
523k
            pgs->color[0].effective_opm, pgs->color[1].effective_opm);
678
679
523k
        pcs->type->set_overprint(pcs, pgs);
680
523k
    }
681
523k
    return code;
682
523k
}
683
684
/* setoverprint (non-stroke case) interpreter code
685
   ensures that this is called when appropriate. This
686
   should only be coming when we are doing PS files.
687
   As they don't have separate stroke and fill overprint
688
   controls */
689
void
690
gs_setoverprint(gs_gstate * pgs, bool ovp)
691
2.13M
{
692
2.13M
    pgs->overprint = ovp;
693
2.13M
    pgs->stroke_overprint = ovp;
694
2.13M
}
695
696
/* currentoverprint */
697
bool
698
gs_currentoverprint(const gs_gstate * pgs)
699
1.06M
{
700
1.06M
    return pgs->overprint;
701
1.06M
}
702
703
/* setstrokeoverprint */
704
void
705
gs_setstrokeoverprint(gs_gstate * pgs, bool ovp)
706
246k
{
707
246k
    pgs->stroke_overprint = ovp;
708
246k
}
709
710
/* currentstrokeoverprint */
711
bool
712
gs_currentstrokeoverprint(const gs_gstate * pgs)
713
15.2k
{
714
15.2k
    return pgs->stroke_overprint;
715
15.2k
}
716
717
/* setstrokeoverprint */
718
void
719
gs_setfilloverprint(gs_gstate * pgs, bool ovp)
720
251k
{
721
251k
    pgs->overprint = ovp;
722
251k
}
723
724
/* currentstrokeoverprint */
725
bool
726
gs_currentfilloverprint(const gs_gstate * pgs)
727
11.5k
{
728
11.5k
    return pgs->overprint;
729
11.5k
}
730
731
/* setoverprintmode */
732
int
733
gs_setoverprintmode(gs_gstate * pgs, int mode)
734
189k
{
735
189k
    if (mode < 0 || mode > 1)
736
9
        return_error(gs_error_rangecheck);
737
189k
    pgs->overprint_mode = mode;
738
739
189k
    return 0;
740
189k
}
741
742
/* currentoverprintmode */
743
int
744
gs_currentoverprintmode(const gs_gstate * pgs)
745
1
{
746
1
    return pgs->overprint_mode;
747
1
}
748
749
void
750
gs_setcpsimode(gs_memory_t *mem, bool mode)
751
0
{
752
0
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
753
754
0
    libctx->core->CPSI_mode = mode;
755
0
}
756
757
/* currentcpsimode */
758
bool
759
gs_currentcpsimode(const gs_memory_t * mem)
760
657M
{
761
657M
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
762
763
657M
    return libctx->core->CPSI_mode;
764
657M
}
765
766
/* The edgebuffer based scanconverter can only cope with values of 0
767
 * or 0.5 (i.e. 'center of pixel' or 'any part of pixel'). These
768
 * are the only values required for correct behaviour according to
769
 * the PDF and PS specs. Therefore, if we are using the edgebuffer
770
 * based scan converter, force these values. */
771
static void
772
sanitize_fill_adjust(gs_gstate * pgs)
773
16.3M
{
774
16.3M
    int scanconverter = gs_getscanconverter(pgs->memory);
775
16.3M
    if (scanconverter >= GS_SCANCONVERTER_EDGEBUFFER || (GS_SCANCONVERTER_DEFAULT_IS_EDGEBUFFER && scanconverter == GS_SCANCONVERTER_DEFAULT)) {
776
16.3M
        fixed adjust = (pgs->fill_adjust.x >= float2fixed(0.25) || pgs->fill_adjust.y >= float2fixed(0.25) ? fixed_half : 0);
777
16.3M
        pgs->fill_adjust.x = adjust;
778
16.3M
        pgs->fill_adjust.y = adjust;
779
16.3M
    }
780
16.3M
}
781
782
void
783
gs_setscanconverter(gs_gstate * gs, int converter)
784
5.97k
{
785
5.97k
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(gs->memory);
786
787
5.97k
    libctx->core->scanconverter = converter;
788
789
5.97k
    sanitize_fill_adjust(gs);
790
5.97k
}
791
792
/* getscanconverter */
793
int
794
gs_getscanconverter(const gs_memory_t * mem)
795
32.0M
{
796
32.0M
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
797
798
32.0M
    return libctx->core->scanconverter;
799
32.0M
}
800
801
/* setrenderingintent
802
 *
803
 *  Use ICC numbers from Table 18 (section 6.1.11) rather than the PDF order
804
 *  to reduce re-coding and confusion.
805
 *    Perceptual            0
806
 *    Relative Colorimetric 1
807
 *    Saturation            2
808
 *    AbsoluteColorimetric  3
809
 */
810
int
811
78.9k
gs_setrenderingintent(gs_gstate *pgs, int ri) {
812
78.9k
    if (ri < 0 || ri > 3)
813
0
        return_error(gs_error_rangecheck);
814
78.9k
    pgs->renderingintent = ri;
815
78.9k
    return 0;
816
78.9k
}
817
818
/* currentrenderingintent */
819
int
820
gs_currentrenderingintent(const gs_gstate * pgs)
821
0
{
822
0
    return pgs->renderingintent;
823
0
}
824
825
int
826
0
gs_setblackptcomp(gs_gstate *pgs, bool bkpt) {
827
0
    pgs->blackptcomp = bkpt;
828
0
    return 0;
829
0
}
830
831
/* currentrenderingintent */
832
bool
833
gs_currentblackptcomp(const gs_gstate * pgs)
834
0
{
835
0
    return pgs->blackptcomp;
836
0
}
837
838
/*
839
 * Reset most of the graphics state.
840
 */
841
int
842
gs_initgraphics(gs_gstate * pgs)
843
1.44M
{
844
1.44M
    int code;
845
1.44M
    const gs_gstate gstate_initial = {
846
1.44M
            gs_gstate_initial(1.0)
847
1.44M
        };
848
1.44M
    gs_matrix m;
849
1.44M
    gs_make_identity(&m);
850
851
1.44M
    gs_initmatrix(pgs);
852
1.44M
    if ((code = gs_newpath(pgs)) < 0 ||
853
1.44M
        (code = gs_initclip(pgs)) < 0 ||
854
1.44M
        (code = gs_setlinewidth(pgs, 1.0)) < 0 ||
855
1.44M
        (code = gs_setlinestartcap(pgs, gstate_initial.line_params.start_cap)) < 0 ||
856
1.44M
        (code = gs_setlineendcap(pgs, gstate_initial.line_params.end_cap)) < 0 ||
857
1.44M
        (code = gs_setlinedashcap(pgs, gstate_initial.line_params.dash_cap)) < 0 ||
858
1.44M
        (code = gs_setlinejoin(pgs, gstate_initial.line_params.join)) < 0 ||
859
1.44M
        (code = gs_setcurvejoin(pgs, gstate_initial.line_params.curve_join)) < 0 ||
860
1.44M
        (code = gs_setdash(pgs, (float *)0, 0, 0.0)) < 0 ||
861
1.44M
        (gs_setdashadapt(pgs, false),
862
1.44M
         (code = gs_setdotlength(pgs, 0.0, false))) < 0 ||
863
1.44M
        (code = gs_setdotorientation(pgs)) < 0 ||
864
1.44M
        (code = gs_setmiterlimit(pgs, gstate_initial.line_params.miter_limit)) < 0
865
1.44M
        )
866
0
        return code;
867
1.44M
    gs_init_rop(pgs);
868
    /* Initialize things so that gx_remap_color won't crash. */
869
1.44M
    if (pgs->icc_manager->default_gray == 0x00) {
870
174k
        gs_color_space  *pcs1, *pcs2;
871
872
174k
        pcs1 = gs_cspace_new_DeviceGray(pgs->memory);
873
174k
        if (pcs1 == NULL)
874
0
            return_error(gs_error_unknownerror);
875
876
174k
        if (pgs->color[0].color_space != NULL) {
877
0
            gs_setcolorspace(pgs, pcs1);
878
0
            rc_decrement_cs(pcs1, "gs_initgraphics");
879
174k
        } else {
880
174k
            pgs->color[0].color_space = pcs1;
881
174k
            gs_setcolorspace(pgs, pcs1);
882
174k
        }
883
174k
        code = gx_set_dev_color(pgs);
884
174k
        if (code < 0)
885
0
            return code;
886
887
174k
        gs_swapcolors_quick(pgs); /* To color 1 */
888
889
174k
        pcs2 = gs_cspace_new_DeviceGray(pgs->memory);
890
174k
        if (pcs2 == NULL)
891
0
            return_error(gs_error_unknownerror);
892
893
174k
        if (pgs->color[0].color_space != NULL) {
894
0
            gs_setcolorspace(pgs, pcs2);
895
0
            rc_decrement_cs(pcs2, "gs_initgraphics");
896
174k
        } else {
897
174k
            pgs->color[0].color_space = pcs2;
898
174k
            gs_setcolorspace(pgs, pcs2);
899
174k
        }
900
174k
        code = gx_set_dev_color(pgs);
901
902
174k
        gs_swapcolors_quick(pgs); /* To color 0 */
903
904
174k
        if (code < 0)
905
0
            return code;
906
907
1.26M
    } else {
908
1.26M
        gs_color_space  *pcs1, *pcs2;
909
910
1.26M
        pcs1 = gs_cspace_new_ICC(pgs->memory, pgs, 1);
911
1.26M
        if (pcs1 == NULL)
912
0
            return_error(gs_error_unknownerror);
913
914
1.26M
        if (pgs->color[0].color_space != NULL) {
915
996k
            gs_setcolorspace(pgs, pcs1);
916
996k
            rc_decrement_cs(pcs1, "gs_initgraphics");
917
996k
        } else {
918
270k
            pgs->color[0].color_space = pcs1;
919
270k
            gs_setcolorspace(pgs, pcs1);
920
270k
        }
921
1.26M
        code = gx_set_dev_color(pgs);
922
1.26M
        if (code < 0)
923
0
            return code;
924
925
1.26M
        gs_swapcolors_quick(pgs); /* To color 1 */
926
1.26M
        pcs2 = gs_cspace_new_ICC(pgs->memory, pgs, 1);
927
1.26M
        if (pcs2 == NULL)
928
0
            return_error(gs_error_unknownerror);
929
930
1.26M
        if (pgs->color[0].color_space != NULL) {
931
996k
            gs_setcolorspace(pgs, pcs2);
932
996k
            rc_decrement_cs(pcs2, "gs_initgraphics");
933
996k
        } else {
934
270k
            pgs->color[0].color_space = pcs2;
935
270k
            gs_setcolorspace(pgs, pcs2);
936
270k
        }
937
1.26M
        code = gx_set_dev_color(pgs);
938
939
1.26M
        gs_swapcolors_quick(pgs); /* To color 0 */
940
941
1.26M
        if (code < 0)
942
0
            return code;
943
1.26M
    }
944
1.44M
    pgs->in_cachedevice = 0;
945
946
1.44M
    code = gs_settextspacing(pgs, (double)0.0);
947
1.44M
    if (code < 0)
948
0
        goto exit;
949
1.44M
    code = gs_settextleading(pgs, (double)0.0);
950
1.44M
    if (code < 0)
951
0
        goto exit;
952
953
1.44M
    gs_settextrenderingmode(pgs, 0);
954
955
1.44M
    code = gs_setwordspacing(pgs, (double)0.0);
956
1.44M
    if (code < 0)
957
0
        goto exit;
958
1.44M
    code = gs_settexthscaling(pgs, (double)100.0);
959
1.44M
    if (code < 0)
960
0
        goto exit;
961
962
1.44M
    gs_setaccuratecurves(pgs, true);
963
964
1.44M
    code = gs_setstrokeconstantalpha(pgs, 1.0);
965
1.44M
    if (code < 0)
966
0
        goto exit;
967
1.44M
    code = gs_setfillconstantalpha(pgs, 1.0);
968
1.44M
    if (code < 0)
969
0
        goto exit;
970
1.44M
    code = gs_setalphaisshape(pgs, 0);
971
1.44M
    if (code < 0)
972
0
        goto exit;
973
1.44M
    code = gs_setblendmode(pgs, BLEND_MODE_Compatible);
974
1.44M
    if (code < 0)
975
0
        goto exit;
976
1.44M
    code = gs_settextknockout(pgs, true);
977
1.44M
    if (code < 0)
978
0
        goto exit;
979
1.44M
    code = gs_setsmoothness(pgs, 0.02); /* Match gs code */
980
1.44M
    if (code < 0)
981
0
        goto exit;
982
983
1.44M
    code = gs_settextmatrix(pgs, &m);
984
1.44M
    if (code < 0)
985
0
        goto exit;
986
987
1.44M
    code = gs_settextlinematrix(pgs, &m);
988
1.44M
    if (code < 0)
989
0
        goto exit;
990
1.44M
exit:
991
1.44M
    return code;
992
1.44M
}
993
994
/* setfilladjust */
995
int
996
gs_setfilladjust(gs_gstate * pgs, double adjust_x, double adjust_y)
997
16.3M
{
998
16.3M
#define CLAMP_TO_HALF(v)\
999
32.6M
    ((v) <= 0 ? fixed_0 : (v) >= 0.5 ? fixed_half : float2fixed(v));
1000
1001
16.3M
    pgs->fill_adjust.x = CLAMP_TO_HALF(adjust_x);
1002
16.3M
    pgs->fill_adjust.y = CLAMP_TO_HALF(adjust_y);
1003
1004
16.3M
    sanitize_fill_adjust(pgs);
1005
1006
16.3M
    return 0;
1007
16.3M
#undef CLAMP_TO_HALF
1008
16.3M
}
1009
1010
/* currentfilladjust */
1011
int
1012
gs_currentfilladjust(const gs_gstate * pgs, gs_point * adjust)
1013
258k
{
1014
258k
    adjust->x = fixed2float(pgs->fill_adjust.x);
1015
258k
    adjust->y = fixed2float(pgs->fill_adjust.y);
1016
258k
    return 0;
1017
258k
}
1018
1019
/* setlimitclamp */
1020
void
1021
gs_setlimitclamp(gs_gstate * pgs, bool clamp)
1022
751k
{
1023
751k
    pgs->clamp_coordinates = clamp;
1024
751k
}
1025
1026
/* currentlimitclamp */
1027
bool
1028
gs_currentlimitclamp(const gs_gstate * pgs)
1029
0
{
1030
0
    return pgs->clamp_coordinates;
1031
0
}
1032
1033
/* settextrenderingmode */
1034
void
1035
gs_settextrenderingmode(gs_gstate * pgs, uint trm)
1036
2.03M
{
1037
2.03M
    pgs->text_rendering_mode = trm;
1038
2.03M
}
1039
1040
/* currenttextrenderingmode */
1041
uint
1042
gs_currenttextrenderingmode(const gs_gstate * pgs)
1043
20.8M
{
1044
20.8M
    return pgs->text_rendering_mode;
1045
20.8M
}
1046
1047
double
1048
gs_currenttextspacing(const gs_gstate *pgs)
1049
13.5M
{
1050
13.5M
    return pgs->textspacing;
1051
13.5M
}
1052
1053
int
1054
gs_settextspacing(gs_gstate *pgs, double Tc)
1055
2.14M
{
1056
2.14M
    int code = 0;
1057
2.14M
    gs_fixed_point dxy;
1058
1059
2.14M
    code = gs_distance_transform2fixed(&pgs->ctm, Tc, 1, &dxy);
1060
2.14M
    if (code < 0)
1061
5.63k
        return code;
1062
1063
2.13M
    pgs->textspacing = (float)Tc;
1064
2.13M
    return 0;
1065
2.14M
}
1066
1067
double
1068
gs_currenttextleading(const gs_gstate *pgs)
1069
0
{
1070
0
    return pgs->textleading;
1071
0
}
1072
1073
int
1074
gs_settextleading(gs_gstate *pgs, double TL)
1075
1.84M
{
1076
1.84M
    pgs->textleading = (float)TL;
1077
1.84M
    return 0;
1078
1.84M
}
1079
1080
double
1081
gs_currenttextrise(const gs_gstate *pgs)
1082
0
{
1083
0
    return pgs->textrise;
1084
0
}
1085
1086
int
1087
gs_settextrise(gs_gstate *pgs, double Ts)
1088
3.62k
{
1089
3.62k
    pgs->textrise = (float)Ts;
1090
3.62k
    return 0;
1091
3.62k
}
1092
1093
double
1094
gs_currentwordspacing(const gs_gstate *pgs)
1095
13.5M
{
1096
13.5M
    return pgs->wordspacing;
1097
13.5M
}
1098
1099
int
1100
gs_setwordspacing(gs_gstate *pgs, double Tw)
1101
1.59M
{
1102
1.59M
    pgs->wordspacing = (float)Tw;
1103
1.59M
    return 0;
1104
1.59M
}
1105
1106
int
1107
gs_settexthscaling(gs_gstate *pgs, double Tz)
1108
1.54M
{
1109
1.54M
    pgs->texthscaling = (float)Tz;
1110
1.54M
    return 0;
1111
1.54M
}
1112
1113
double
1114
gs_currenttexthscaling(const gs_gstate *pgs)
1115
0
{
1116
0
    return pgs->texthscaling;
1117
0
}
1118
1119
int
1120
gs_setPDFfontsize(gs_gstate *pgs, double Tf)
1121
1.23M
{
1122
1.23M
    pgs->PDFfontsize = (float)Tf;
1123
1.23M
    return 0;
1124
1.23M
}
1125
1126
double
1127
gs_currentPDFfontsize(const gs_gstate *pgs)
1128
0
{
1129
0
    return pgs->PDFfontsize;
1130
0
}
1131
1132
int
1133
gs_settextlinematrix(gs_gstate *pgs, gs_matrix *m)
1134
6.63M
{
1135
6.63M
    pgs->textlinematrix.xx = m->xx;
1136
6.63M
    pgs->textlinematrix.xy = m->xy;
1137
6.63M
    pgs->textlinematrix.yx = m->yx;
1138
6.63M
    pgs->textlinematrix.yy = m->yy;
1139
6.63M
    pgs->textlinematrix.tx = m->tx;
1140
6.63M
    pgs->textlinematrix.ty = m->ty;
1141
6.63M
    return 0;
1142
6.63M
}
1143
int
1144
gs_gettextlinematrix(gs_gstate *pgs, gs_matrix *m)
1145
0
{
1146
0
    m->xx = pgs->textlinematrix.xx;
1147
0
    m->xy = pgs->textlinematrix.xy;
1148
0
    m->yx = pgs->textlinematrix.yx;
1149
0
    m->yy = pgs->textlinematrix.yy;
1150
0
    m->tx = pgs->textlinematrix.tx;
1151
0
    m->ty = pgs->textlinematrix.ty;
1152
0
    return 0;
1153
0
}
1154
1155
int
1156
gs_settextmatrix(gs_gstate *pgs, gs_matrix *m)
1157
6.63M
{
1158
6.63M
    pgs->textmatrix.xx = m->xx;
1159
6.63M
    pgs->textmatrix.xy = m->xy;
1160
6.63M
    pgs->textmatrix.yx = m->yx;
1161
6.63M
    pgs->textmatrix.yy = m->yy;
1162
6.63M
    pgs->textmatrix.tx = m->tx;
1163
6.63M
    pgs->textmatrix.ty = m->ty;
1164
6.63M
    return 0;
1165
6.63M
}
1166
int
1167
gs_gettextmatrix(gs_gstate *pgs, gs_matrix *m)
1168
0
{
1169
0
    m->xx = pgs->textmatrix.xx;
1170
0
    m->xy = pgs->textmatrix.xy;
1171
0
    m->yx = pgs->textmatrix.yx;
1172
0
    m->yy = pgs->textmatrix.yy;
1173
0
    m->tx = pgs->textmatrix.tx;
1174
0
    m->ty = pgs->textmatrix.ty;
1175
0
    return 0;
1176
0
}
1177
1178
1179
/* sethpglpathmode */
1180
void
1181
gs_sethpglpathmode(gs_gstate * pgs, bool path)
1182
447k
{
1183
447k
    pgs->hpgl_path_mode = path;
1184
447k
}
1185
1186
/* currenthpglpathmode */
1187
bool
1188
gs_currenthpglpathmode(const gs_gstate * pgs)
1189
0
{
1190
0
    return pgs->hpgl_path_mode;
1191
0
}
1192
1193
/* ------ Internal routines ------ */
1194
1195
/* Free the privately allocated parts of a gstate. */
1196
static void
1197
gstate_free_parts(gs_gstate * parts, gs_memory_t * mem, client_name_t cname)
1198
86.2M
{
1199
86.2M
    gs_free_object(mem, parts->color[1].dev_color, cname);
1200
86.2M
    gs_free_object(mem, parts->color[1].ccolor, cname);
1201
86.2M
    gs_free_object(mem, parts->color[0].dev_color, cname);
1202
86.2M
    gs_free_object(mem, parts->color[0].ccolor, cname);
1203
86.2M
    parts->color[1].dev_color = 0;
1204
86.2M
    parts->color[1].ccolor = 0;
1205
86.2M
    parts->color[0].dev_color = 0;
1206
86.2M
    parts->color[0].ccolor = 0;
1207
86.2M
    if (!parts->effective_clip_shared && parts->effective_clip_path) {
1208
0
        gx_cpath_free(parts->effective_clip_path, cname);
1209
0
        parts->effective_clip_path = 0;
1210
0
    }
1211
86.2M
    gx_cpath_free(parts->clip_path, cname);
1212
86.2M
    parts->clip_path = 0;
1213
86.2M
    if (parts->path) {
1214
43.2M
        gx_path_free(parts->path, cname);
1215
43.2M
        parts->path = 0;
1216
43.2M
    }
1217
86.2M
}
1218
1219
static inline void
1220
gstate_parts_init_dev_color(gx_device_color *dc)
1221
86.5M
{
1222
86.5M
    gx_device_color_type dct = dc->type;
1223
86.5M
    gs_graphics_type_tag_t gtt = dc->tag;
1224
86.5M
    memset(dc, 0x00, sizeof(gx_device_color));
1225
86.5M
    dc->type = dct;
1226
86.5M
    dc->tag = gtt;
1227
86.5M
}
1228
1229
/* Allocate the privately allocated parts of a gstate. */
1230
static int
1231
gstate_alloc_parts(gs_gstate * parts, const gs_gstate * shared,
1232
                   gs_memory_t * mem, client_name_t cname)
1233
43.2M
{
1234
43.2M
    gs_memory_t *path_mem = gstate_path_memory(mem);
1235
1236
43.2M
    parts->path =
1237
43.2M
        (shared ?
1238
42.8M
         gx_path_alloc_shared(shared->path, path_mem,
1239
42.8M
                              "gstate_alloc_parts(path)") :
1240
43.2M
         gx_path_alloc(path_mem, "gstate_alloc_parts(path)"));
1241
43.2M
    parts->clip_path =
1242
43.2M
        (shared ?
1243
42.8M
         gx_cpath_alloc_shared(shared->clip_path, mem,
1244
42.8M
                               "gstate_alloc_parts(clip_path)") :
1245
43.2M
         gx_cpath_alloc(mem, "gstate_alloc_parts(clip_path)"));
1246
43.2M
    if (!shared || shared->effective_clip_shared) {
1247
43.2M
        parts->effective_clip_path = parts->clip_path;
1248
43.2M
        parts->effective_clip_shared = true;
1249
43.2M
    } else {
1250
0
        parts->effective_clip_path =
1251
0
            gx_cpath_alloc_shared(shared->effective_clip_path, mem,
1252
0
                                  "gstate_alloc_parts(effective_clip_path)");
1253
0
        parts->effective_clip_shared = false;
1254
0
    }
1255
43.2M
    parts->color[0].color_space = NULL;
1256
43.2M
    parts->color[1].color_space = NULL;
1257
43.2M
    parts->color[0].ccolor =
1258
43.2M
        gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
1259
43.2M
    parts->color[1].ccolor =
1260
43.2M
        gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
1261
43.2M
    parts->color[0].dev_color =
1262
43.2M
        gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
1263
43.2M
    parts->color[1].dev_color =
1264
43.2M
        gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
1265
43.2M
    if (parts->path == 0 || parts->clip_path == 0 ||
1266
43.2M
        parts->effective_clip_path == 0 ||
1267
43.2M
        parts->color[0].ccolor == 0 || parts->color[0].dev_color == 0 ||
1268
43.2M
        parts->color[1].ccolor == 0 || parts->color[1].dev_color == 0
1269
43.2M
        ) {
1270
3
        gstate_free_parts(parts, mem, cname);
1271
3
        return_error(gs_error_VMerror);
1272
3
    }
1273
43.2M
    gstate_parts_init_dev_color(parts->color[0].dev_color);
1274
43.2M
    gstate_parts_init_dev_color(parts->color[1].dev_color);
1275
43.2M
    return 0;
1276
43.2M
}
1277
1278
/*
1279
 * Allocate a gstate and its contents.
1280
 * If pfrom is not NULL, the path, clip_path, and (if distinct from both
1281
 * clip_path and view_clip) effective_clip_path share the segments of
1282
 * pfrom's corresponding path(s).
1283
 */
1284
static gs_gstate *
1285
gstate_alloc(gs_memory_t * mem, client_name_t cname, const gs_gstate * pfrom)
1286
43.2M
{
1287
43.2M
    gs_gstate *pgs =
1288
43.2M
        gs_alloc_struct(mem, gs_gstate, &st_gs_gstate, cname);
1289
1290
43.2M
    if (pgs == NULL)
1291
1
        return NULL;
1292
43.2M
    memset(pgs, 0x00, sizeof(gs_gstate));
1293
43.2M
    if (gstate_alloc_parts(pgs, pfrom, mem, cname) < 0) {
1294
3
        gs_free_object(mem, pgs, cname);
1295
3
        return NULL;
1296
3
    }
1297
43.2M
    pgs->memory = mem;
1298
43.2M
    return pgs;
1299
43.2M
}
1300
1301
/* Copy the dash pattern from one gstate to another. */
1302
static int
1303
gstate_copy_dash(gs_memory_t *mem, gx_dash_params *dash , const gs_gstate * pfrom)
1304
98.6k
{
1305
98.6k
    return gx_set_dash(dash, pfrom->line_params.dash.pattern,
1306
98.6k
                      pfrom->line_params.dash.pattern_size,
1307
98.6k
                      pfrom->line_params.dash.offset, mem);
1308
98.6k
}
1309
1310
typedef struct {
1311
    gs_gstate_parts  parts;
1312
    gx_dash_params   dash;
1313
} gs_gstate_clone_data;
1314
1315
static gs_gstate *
1316
gstate_clone_core(const gs_gstate               *pfrom,
1317
                        gs_memory_t             *mem,
1318
                        client_name_t            cname,
1319
                        gs_gstate_clone_data    *clone_data,
1320
                        gs_gstate_copy_reason_t  reason)
1321
42.8M
{
1322
42.8M
    gs_gstate *pgs = gstate_alloc(mem, cname, pfrom);
1323
42.8M
    void *pdata = NULL;
1324
1325
42.8M
    if (pgs == NULL)
1326
4
        return NULL;
1327
42.8M
    if (pfrom->client_data != NULL) {
1328
42.6M
        pdata = (*pfrom->client_procs.alloc) (mem);
1329
1330
42.6M
        if (pdata == NULL ||
1331
42.6M
            gstate_copy_client_data(pfrom, pdata, pfrom->client_data,
1332
42.6M
                                    reason) < 0)
1333
0
            goto failEarly;
1334
42.6M
    }
1335
    /* Copy the dash and dash pattern if necessary. */
1336
42.8M
    clone_data->dash = gs_currentlineparams_inline(pfrom)->dash;
1337
42.8M
    if (clone_data->dash.pattern) {
1338
97.8k
        int code;
1339
1340
97.8k
        clone_data->dash.pattern = NULL; /* Ensures a fresh allocation */
1341
97.8k
        code = gstate_copy_dash(mem, &clone_data->dash, pfrom);
1342
97.8k
        if (code < 0)
1343
0
            goto fail;
1344
97.8k
    }
1345
    /* Some records within pgs are allocated. We copy pfrom into pgs
1346
     * wholesale (to avoid problems with the structure being updated and
1347
     * us having to keep it in sync), so we copy those allocated regions
1348
     * out first. The caller of this routine will then put them back
1349
     * into either pgs or pfrom as appropriate. */
1350
42.8M
    GSTATE_ASSIGN_PARTS(&clone_data->parts, pgs);
1351
42.8M
    *pgs = *pfrom;
1352
42.8M
    pgs->client_data = pdata;
1353
1354
42.8M
    gs_gstate_copied(pgs);
1355
    /* Don't do anything to clip_stack. */
1356
1357
42.8M
    rc_increment(pgs->device);
1358
42.8M
    *clone_data->parts.color[0].ccolor    = *pgs->color[0].ccolor;
1359
42.8M
    *clone_data->parts.color[0].dev_color = *pgs->color[0].dev_color;
1360
42.8M
    *clone_data->parts.color[1].ccolor    = *pgs->color[1].ccolor;
1361
42.8M
    *clone_data->parts.color[1].dev_color = *pgs->color[1].dev_color;
1362
42.8M
    cs_adjust_counts_icc(pgs, 1);
1363
42.8M
    cs_adjust_swappedcounts_icc(pgs, 1);
1364
1365
42.8M
    return pgs;
1366
1367
0
  fail:
1368
0
    gs_free_object(mem, clone_data->dash.pattern, cname);
1369
0
    if (pdata != NULL)
1370
0
        (*pfrom->client_procs.free) (pdata, mem, pgs);
1371
0
  failEarly:
1372
0
    gstate_free_parts(pgs, mem, cname);
1373
0
    gs_free_object(mem, pgs, cname);
1374
1375
0
    return NULL;
1376
0
}
1377
1378
1379
/* Clone an existing graphics state for use in gsave. The clone refers
1380
 * to the old contents, and the old state refers to the new contents. */
1381
/* Return NULL if the allocation fails. */
1382
static gs_gstate *
1383
gstate_clone_for_gsave(gs_gstate     *pfrom,
1384
                       client_name_t  cname)
1385
41.7M
{
1386
41.7M
    gs_gstate_clone_data clone_data;
1387
41.7M
    gs_gstate *pgs = gstate_clone_core(pfrom, pfrom->memory, cname,
1388
41.7M
                                       &clone_data, copy_for_gsave);
1389
1390
41.7M
    if (pgs == NULL)
1391
4
        return NULL;
1392
1393
    /* Newly allocated parts go back into pfrom, not pgs! */
1394
41.7M
    GSTATE_ASSIGN_PARTS(pfrom, &clone_data.parts);
1395
41.7M
    gs_currentlineparams_inline(pfrom)->dash = clone_data.dash;
1396
1397
41.7M
    return pgs;
1398
41.7M
}
1399
1400
/* Clone an existing graphics state. The view_clip is not copied. */
1401
/* Return NULL if the allocation fails. */
1402
static gs_gstate *
1403
gstate_clone_for_gstate(const gs_gstate     *pfrom,
1404
                              gs_memory_t   *mem,
1405
                              client_name_t  cname)
1406
1.12M
{
1407
1.12M
    gs_gstate_clone_data clone_data;
1408
1.12M
    gs_gstate *pgs = gstate_clone_core(pfrom, mem, cname, &clone_data,
1409
1.12M
                                       copy_for_gstate);
1410
1411
1.12M
    if (pgs == NULL)
1412
0
        return NULL;
1413
1.12M
    GSTATE_ASSIGN_PARTS(pgs, &clone_data.parts);
1414
1.12M
    pgs->view_clip = NULL;
1415
1.12M
    gs_currentlineparams_inline(pgs)->dash = clone_data.dash;
1416
1.12M
    pgs->memory = mem;
1417
1418
1.12M
    return pgs;
1419
1.12M
}
1420
1421
/* Adjust reference counters for the whole clip stack */
1422
/* accessible from the given point */
1423
static void
1424
clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t cname)
1425
87.3M
{
1426
87.3M
    gx_clip_stack_t *p = cs;
1427
1428
87.3M
    while(p) {
1429
1
        gx_clip_stack_t *q = p;
1430
1
        p = p->next;
1431
1
        rc_adjust(q, delta, cname);
1432
1
    }
1433
87.3M
}
1434
1435
/*
1436
 * Finalization for graphics states. This is where we handle RC for those
1437
 * elements.
1438
 */
1439
void
1440
gs_gstate_finalize(const gs_memory_t *cmem,void *vptr)
1441
43.2M
{
1442
43.2M
    gs_gstate *pgs = (gs_gstate *)vptr;
1443
43.2M
    (void)cmem; /* unused */
1444
1445
43.2M
    if (cmem == NULL)
1446
0
        return;     /* place for breakpoint */
1447
43.2M
    gstate_free_contents(pgs);
1448
43.2M
}
1449
1450
/* Release the composite parts of a graphics state, */
1451
/* but not the state itself. */
1452
static void
1453
gstate_free_contents(gs_gstate * pgs)
1454
86.2M
{
1455
86.2M
    gs_memory_t *mem = pgs->memory;
1456
86.2M
    const char *const cname = "gstate_free_contents";
1457
1458
86.2M
    rc_decrement(pgs->device, cname);
1459
86.2M
    pgs->device = 0;
1460
86.2M
    clip_stack_rc_adjust(pgs->clip_stack, -1, cname);
1461
86.2M
    pgs->clip_stack = 0;
1462
86.2M
    if (pgs->view_clip != NULL && pgs->level == 0) {
1463
444k
        gx_cpath_free(pgs->view_clip, cname);
1464
444k
        pgs->view_clip = NULL;
1465
444k
    }
1466
86.2M
    if (pgs->client_data != 0)
1467
42.9M
        (*pgs->client_procs.free) (pgs->client_data, mem, pgs);
1468
86.2M
    pgs->client_data = 0;
1469
86.2M
    cs_adjust_counts_icc(pgs, -1);
1470
86.2M
    cs_adjust_swappedcounts_icc(pgs, -1);
1471
86.2M
    pgs->color[0].color_space = 0;
1472
86.2M
    pgs->color[1].color_space = 0;
1473
86.2M
    gs_free_object(mem, pgs->line_params.dash.pattern, cname);
1474
86.2M
    pgs->line_params.dash.pattern = 0;
1475
86.2M
    gstate_free_parts(pgs, mem, cname);     /* this also clears pointers to freed elements */
1476
86.2M
    gs_gstate_release(pgs);
1477
86.2M
}
1478
1479
/* Copy one gstate to another. */
1480
static int
1481
gstate_copy(gs_gstate * pto, const gs_gstate * pfrom,
1482
            gs_gstate_copy_reason_t reason, client_name_t cname)
1483
38.3k
{
1484
38.3k
    gs_gstate_parts parts;
1485
1486
38.3k
    GSTATE_ASSIGN_PARTS(&parts, pto);
1487
    /* Copy the dash pattern if necessary. */
1488
38.3k
    if (pfrom->line_params.dash.pattern || pto->line_params.dash.pattern) {
1489
808
        int code = gstate_copy_dash(pto->memory,
1490
808
                             &(gs_currentlineparams_inline(pto)->dash), pfrom);
1491
1492
808
        if (code < 0)
1493
0
            return code;
1494
808
    }
1495
    /*
1496
     * It's OK to decrement the counts before incrementing them,
1497
     * because anything that is going to survive has a count of
1498
     * at least 2 (pto and somewhere else) initially.
1499
     * Handle references from contents.
1500
     */
1501
38.3k
    cs_adjust_counts_icc(pto, -1);
1502
38.3k
    cs_adjust_swappedcounts_icc(pto, -1);
1503
38.3k
    gx_path_assign_preserve(pto->path, pfrom->path);
1504
38.3k
    gx_cpath_assign_preserve(pto->clip_path, pfrom->clip_path);
1505
    /*
1506
     * effective_clip_shared will be copied, but we need to do the
1507
     * right thing with effective_clip_path.
1508
     */
1509
38.3k
    if (pfrom->effective_clip_shared) {
1510
        /*
1511
         * pfrom->effective_clip_path is either pfrom->view_clip or
1512
         * pfrom->clip_path.
1513
         */
1514
38.3k
        parts.effective_clip_path =
1515
38.3k
            (pfrom->effective_clip_path == pfrom->view_clip ?
1516
38.3k
             pto->view_clip : parts.clip_path);
1517
38.3k
    } else
1518
0
        gx_cpath_assign_preserve(pto->effective_clip_path,
1519
0
                                 pfrom->effective_clip_path);
1520
38.3k
    *parts.color[0].ccolor    = *pfrom->color[0].ccolor;
1521
38.3k
    *parts.color[0].dev_color = *pfrom->color[0].dev_color;
1522
38.3k
    *parts.color[1].ccolor    = *pfrom->color[1].ccolor;
1523
38.3k
    *parts.color[1].dev_color = *pfrom->color[1].dev_color;
1524
    /* Handle references from gstate object. */
1525
38.3k
    rc_pre_assign(pto->device, pfrom->device, cname);
1526
38.3k
    if (pto->clip_stack != pfrom->clip_stack) {
1527
0
        clip_stack_rc_adjust(pfrom->clip_stack, 1, cname);
1528
0
        clip_stack_rc_adjust(pto->clip_stack, -1, cname);
1529
0
    }
1530
38.3k
    {
1531
38.3k
        struct gx_pattern_cache_s *pcache = pto->pattern_cache;
1532
38.3k
        void *pdata = pto->client_data;
1533
38.3k
        gs_memory_t *mem = pto->memory;
1534
38.3k
        gs_gstate *saved = pto->saved;
1535
38.3k
        float *pattern = pto->line_params.dash.pattern;
1536
1537
38.3k
        gs_gstate_pre_assign(pto, (const gs_gstate *)pfrom);
1538
38.3k
        *pto = *pfrom;
1539
38.3k
        pto->client_data = pdata;
1540
38.3k
        pto->memory = mem;
1541
38.3k
        pto->saved = saved;
1542
38.3k
        pto->line_params.dash.pattern = pattern;
1543
38.3k
        if (pto->pattern_cache == 0)
1544
0
            pto->pattern_cache = pcache;
1545
38.3k
        if (pfrom->client_data != 0) {
1546
            /* We need to break 'const' here. */
1547
37.0k
            gstate_copy_client_data((gs_gstate *) pfrom, pdata,
1548
37.0k
                                    pfrom->client_data, reason);
1549
37.0k
        }
1550
38.3k
    }
1551
38.3k
    GSTATE_ASSIGN_PARTS(pto, &parts);
1552
38.3k
    cs_adjust_counts_icc(pto, 1);
1553
38.3k
    cs_adjust_swappedcounts_icc(pto, 1);
1554
38.3k
    pto->show_gstate =
1555
38.3k
        (pfrom->show_gstate == pfrom ? pto : 0);
1556
38.3k
    return 0;
1557
38.3k
}
1558
1559
/* Accessories. */
1560
gs_id gx_get_clip_path_id(gs_gstate *pgs)
1561
78.6k
{
1562
78.6k
    return pgs->clip_path->id;
1563
78.6k
}
1564
1565
void gs_swapcolors_quick(const gs_gstate *cpgs)
1566
24.3M
{
1567
24.3M
    union {
1568
24.3M
        const gs_gstate *cpgs;
1569
24.3M
        gs_gstate *pgs;
1570
24.3M
    } const_breaker;
1571
24.3M
    gs_gstate *pgs;
1572
24.3M
    struct gx_cie_joint_caches_s *tmp_cie;
1573
24.3M
    gs_devicen_color_map          tmp_ccm;
1574
24.3M
    gs_client_color              *tmp_cc;
1575
24.3M
    int                           tmp;
1576
24.3M
    gx_device_color              *tmp_dc;
1577
24.3M
    gs_color_space               *tmp_cs;
1578
1579
    /* Break const just once, neatly, here rather than
1580
     * hackily in every caller. */
1581
24.3M
    const_breaker.cpgs = cpgs;
1582
24.3M
    pgs = const_breaker.pgs;
1583
1584
24.3M
    tmp_cc               = pgs->color[0].ccolor;
1585
24.3M
    pgs->color[0].ccolor = pgs->color[1].ccolor;
1586
24.3M
    pgs->color[1].ccolor = tmp_cc;
1587
1588
24.3M
    tmp_dc                  = pgs->color[0].dev_color;
1589
24.3M
    pgs->color[0].dev_color = pgs->color[1].dev_color;
1590
24.3M
    pgs->color[1].dev_color = tmp_dc;
1591
1592
24.3M
    tmp_cs                    = pgs->color[0].color_space;
1593
24.3M
    pgs->color[0].color_space = pgs->color[1].color_space;
1594
24.3M
    pgs->color[1].color_space = tmp_cs;
1595
1596
    /* Overprint and effective_op vary with stroke/fill and cs */
1597
24.3M
    tmp                         = pgs->color[0].effective_opm;
1598
24.3M
    pgs->color[0].effective_opm = pgs->color[1].effective_opm;
1599
24.3M
    pgs->color[1].effective_opm = tmp;
1600
1601
    /* Swap the bits of the gs_gstate that depend on the current color */
1602
24.3M
    tmp_cie                   = pgs->cie_joint_caches;
1603
24.3M
    pgs->cie_joint_caches     = pgs->cie_joint_caches_alt;
1604
24.3M
    pgs->cie_joint_caches_alt = tmp_cie;
1605
1606
24.3M
    tmp_ccm                      = pgs->color_component_map;
1607
24.3M
    pgs->color_component_map     = pgs->color_component_map_alt;
1608
24.3M
    pgs->color_component_map_alt = tmp_ccm;
1609
1610
24.3M
    pgs->is_fill_color = !(pgs->is_fill_color); /* used by overprint for fill_stroke */
1611
24.3M
}
1612
1613
int
1614
gs_clip_bounds_in_user_space(gs_gstate *pgs, gs_rect *ubox)
1615
47.5k
{
1616
47.5k
    gx_clip_path *clip_path;
1617
47.5k
    gs_rect dbox;
1618
47.5k
    int code;
1619
1620
47.5k
    code = gx_effective_clip_path(pgs, &clip_path);
1621
47.5k
    if (code < 0)
1622
0
        return code;
1623
1624
47.5k
    dbox.p.x = fixed2float(clip_path->outer_box.p.x);
1625
47.5k
    dbox.p.y = fixed2float(clip_path->outer_box.p.y);
1626
47.5k
    dbox.q.x = fixed2float(clip_path->outer_box.q.x);
1627
47.5k
    dbox.q.y = fixed2float(clip_path->outer_box.q.y);
1628
47.5k
    return gs_bbox_transform_inverse(&dbox, &ctm_only(pgs), ubox);
1629
47.5k
}