Coverage Report

Created: 2022-04-16 11:23

/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
1.55M
  ((pto)->path = (pfrom)->path, (pto)->clip_path = (pfrom)->clip_path,\
155
1.55M
   (pto)->effective_clip_path = (pfrom)->effective_clip_path,\
156
1.55M
   (pto)->color[0].ccolor = (pfrom)->color[0].ccolor,\
157
1.55M
   (pto)->color[0].dev_color = (pfrom)->color[0].dev_color,\
158
1.55M
   (pto)->color[1].ccolor = (pfrom)->color[1].ccolor,\
159
1.55M
   (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
1.52M
{
169
1.52M
    return (pgs->client_procs.copy_for != 0 ?
170
0
            (*pgs->client_procs.copy_for) (dto, dfrom, reason) :
171
1.52M
            (*pgs->client_procs.copy) (dto, dfrom));
172
1.52M
}
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
776k
{
186
776k
    return gs_memory_stable(mem);
187
776k
}
188
189
/* Allocate and initialize a graphics state. */
190
gs_gstate *
191
gs_gstate_alloc(gs_memory_t * mem)
192
1.35k
{
193
1.35k
    gs_gstate *pgs = gstate_alloc(mem, "gs_gstate_alloc", NULL);
194
1.35k
    gs_memory_t *path_mem = gstate_path_memory(mem);
195
1.35k
    int code;
196
197
1.35k
    if (pgs == 0)
198
0
        return 0;
199
1.35k
    GS_STATE_INIT_VALUES(pgs, 1.0);
200
    /* Need to set up at least enough to make gs_gstate_free happy */
201
1.35k
    pgs->saved = 0;
202
1.35k
    pgs->clip_stack = NULL;
203
1.35k
    pgs->view_clip = NULL;
204
1.35k
    pgs->font = NULL;
205
1.35k
    pgs->root_font = NULL;
206
1.35k
    pgs->show_gstate = NULL;
207
1.35k
    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
1.35k
    code = gs_gstate_initialize(pgs, mem);
215
1.35k
    if (code < 0)
216
0
        goto fail;
217
218
    /* Finish initializing the color rendering state. */
219
220
1.35k
    rc_alloc_struct_1(pgs->halftone, gs_halftone, &st_halftone, mem,
221
1.35k
                      goto fail, "gs_gstate_alloc(halftone)");
222
1.35k
    pgs->halftone->type = ht_type_none;
223
224
    /* Initialize other things not covered by initgraphics */
225
226
1.35k
    pgs->clip_stack = 0;
227
1.35k
    pgs->view_clip = gx_cpath_alloc(path_mem, "gs_gstate_alloc(view_clip)");
228
1.35k
    if (pgs->view_clip == NULL)
229
0
        goto fail;
230
1.35k
    pgs->view_clip->rule = 0;   /* no clipping */
231
1.35k
    pgs->effective_clip_id = pgs->clip_path->id;
232
1.35k
    pgs->effective_view_clip_id = gs_no_id;
233
1.35k
    pgs->in_cachedevice = 0;
234
1.35k
    pgs->device = 0;            /* setting device adjusts refcts */
235
1.35k
    code = gs_nulldevice(pgs);
236
1.35k
    if (code < 0)
237
0
        goto fail;
238
1.35k
    gs_setfillconstantalpha(pgs, 1.0);
239
1.35k
    gs_setstrokeconstantalpha(pgs, 1.0);
240
1.35k
    gs_setalphaisshape(pgs, false);
241
1.35k
    gs_settransfer(pgs, gs_identity_transfer);
242
1.35k
    gs_setflat(pgs, 1.0);
243
1.35k
    gs_setfilladjust(pgs, 0.3, 0.3);
244
1.35k
    gs_setlimitclamp(pgs, false);
245
1.35k
    gs_setstrokeadjust(pgs, true);
246
1.35k
    pgs->font = 0;              /* Not right, but acceptable until the */
247
    /* PostScript code does the first setfont. */
248
1.35k
    pgs->root_font = 0;         /* ditto */
249
1.35k
    pgs->in_charpath = (gs_char_path_mode) 0;
250
1.35k
    pgs->show_gstate = 0;
251
1.35k
    pgs->level = 0;
252
1.35k
    if (gs_initgraphics(pgs) >= 0)
253
1.35k
        return pgs;
254
    /* Something went very wrong. */
255
0
fail:
256
0
    gs_gstate_free(pgs);
257
0
    return 0;
258
1.35k
}
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
8.76k
{
266
8.76k
    pgs->client_data = pdata;
267
8.76k
    pgs->client_procs = *pprocs;
268
8.76k
    pgs->have_pattern_streams = client_has_pattern_streams;
269
8.76k
}
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
101k
{
276
101k
    return pgs->client_data;
277
101k
}
278
279
/* Free the chain of gstates.*/
280
void
281
gs_gstate_free_chain(gs_gstate * pgs)
282
713
{
283
713
   gs_gstate *saved = pgs, *tmp;
284
285
1.42k
   while(saved != 0) {
286
713
       tmp = saved->saved;
287
713
       gs_gstate_free(saved);
288
713
       saved = tmp;
289
713
   }
290
713
}
291
292
/* Free a graphics state. */
293
void
294
gs_gstate_free(gs_gstate * pgs)
295
24.3k
{
296
24.3k
    if (pgs == NULL)
297
0
        return;
298
24.3k
    gstate_free_contents(pgs);
299
24.3k
    gs_free_object(pgs->memory, pgs, "gs_gstate_free");
300
24.3k
}
301
302
/* Save the graphics state. */
303
int
304
gs_gsave(gs_gstate * pgs)
305
750k
{
306
750k
    gs_gstate *pnew = gstate_clone_for_gsave(pgs, "gs_gsave");
307
308
750k
    if (pnew == NULL)
309
0
        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
750k
    pgs->clip_stack = NULL;
319
750k
    pgs->saved = pnew;
320
750k
    if (pgs->show_gstate == pgs)
321
0
        pgs->show_gstate = pnew->show_gstate = pnew;
322
750k
    pgs->trans_flags.xstate_change = false;
323
750k
    pgs->level++;
324
750k
    if_debug2m('g', pgs->memory, "[g]gsave -> "PRI_INTPTR", level = %d\n",
325
750k
              (intptr_t)pnew, pgs->level);
326
750k
    return 0;
327
750k
}
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
15.1k
{
337
15.1k
    int code;
338
15.1k
    gx_clip_path *old_cpath = pgs->view_clip;
339
15.1k
    gx_clip_path *new_cpath;
340
341
15.1k
    if (old_cpath) {
342
15.1k
        new_cpath =
343
15.1k
            gx_cpath_alloc_shared(old_cpath, pgs->memory,
344
15.1k
                                  "gs_gsave_for_save(view_clip)");
345
15.1k
        if (new_cpath == 0)
346
0
            return_error(gs_error_VMerror);
347
15.1k
    } else {
348
0
        new_cpath = 0;
349
0
    }
350
15.1k
    code = gs_gsave(pgs);
351
15.1k
    if (code < 0)
352
0
        goto fail;
353
15.1k
    if (pgs->effective_clip_path == pgs->view_clip)
354
0
        pgs->effective_clip_path = new_cpath;
355
15.1k
    pgs->view_clip = new_cpath;
356
    /* Cut the stack so we can't grestore past here. */
357
15.1k
    *psaved = pgs->saved;
358
15.1k
    pgs->saved = 0;
359
360
15.1k
    code = gs_gsave(pgs);
361
15.1k
    if (code < 0) {
362
0
        pgs->saved = *psaved;
363
0
        *psaved = NULL;
364
0
        gs_grestore(pgs);
365
0
        return code;
366
0
    }
367
15.1k
    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
15.1k
}
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
749k
{
378
749k
    gs_gstate *saved = pgs->saved;
379
749k
    gs_gstate tmp_gstate;
380
749k
    void *pdata = pgs->client_data;
381
749k
    void *sdata;
382
383
749k
    if_debug2m('g', pgs->memory, "[g]grestore "PRI_INTPTR", level was %d\n",
384
749k
               (intptr_t)saved, pgs->level);
385
749k
    if (!saved)
386
0
        return 1;
387
749k
    sdata = saved->client_data;
388
749k
    if (saved->pattern_cache == 0)
389
669
        saved->pattern_cache = pgs->pattern_cache;
390
    /* Swap back the client data pointers. */
391
749k
    pgs->client_data = sdata;
392
749k
    saved->client_data = pdata;
393
749k
    if (pdata != 0 && sdata != 0)
394
749k
        gstate_copy_client_data(pgs, pdata, sdata, copy_for_grestore);
395
749k
    gstate_free_contents(pgs);
396
749k
    tmp_gstate = *pgs;              /* temp after contents freed (with pointers zeroed) */
397
749k
    *pgs = *saved;
398
749k
    if (pgs->show_gstate == saved)
399
0
        pgs->show_gstate = pgs;
400
749k
    *saved = tmp_gstate;            /* restore "freed" state (pointers zeroed after contents freed) */
401
749k
    gs_free_object(pgs->memory, saved, "gs_grestore");
402
403
749k
    return 0;
404
749k
}
405
406
/* Restore the graphics state per PostScript semantics */
407
int
408
gs_grestore(gs_gstate * pgs)
409
749k
{
410
749k
    int code;
411
749k
    if (!pgs->saved)
412
0
        return gs_gsave(pgs);   /* shouldn't ever happen */
413
749k
    code = gs_grestore_only(pgs);
414
749k
    if (code < 0)
415
0
        return code;
416
417
    /* Wraparound: make sure there are always >= 1 saves on stack */
418
749k
    if (pgs->saved)
419
749k
        return 0;
420
0
    return gs_gsave(pgs);
421
749k
}
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
15.1k
{
428
15.1k
    int code;
429
430
15.1k
    while (pgs->saved->saved) {
431
1
        code = gs_grestore(pgs);
432
1
        if (code < 0)
433
0
            return code;
434
1
    }
435
    /* Make sure we don't leave dangling pointers in the caches. */
436
15.1k
    if (pgs->pattern_cache)
437
15.1k
        (*pgs->pattern_cache->free_all) (pgs->pattern_cache);
438
15.1k
    pgs->saved->saved = saved;
439
15.1k
    code = gs_grestore(pgs);
440
15.1k
    if (code < 0)
441
0
        return code;
442
15.1k
    if (pgs->view_clip) {
443
15.1k
        gx_cpath_free(pgs->view_clip, "gs_grestoreall_for_restore");
444
15.1k
        pgs->view_clip = 0;
445
15.1k
    }
446
15.1k
    return gs_grestore(pgs);
447
15.1k
}
448
449
/* Restore to the bottommost graphics state (at this save level). */
450
int
451
gs_grestoreall(gs_gstate * pgs)
452
0
{
453
0
    if (!pgs->saved)            /* shouldn't happen */
454
0
        return gs_gsave(pgs);
455
0
    while (pgs->saved->saved) {
456
0
        int code = gs_grestore(pgs);
457
458
0
        if (code < 0)
459
0
            return code;
460
0
    }
461
0
    return gs_grestore(pgs);
462
0
}
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
23.6k
{
468
23.6k
    gs_gstate *pnew;
469
470
23.6k
    pnew = gstate_clone_for_gstate(pgs, mem, "gs_gstate");
471
23.6k
    if (pnew == NULL)
472
0
        return NULL;
473
23.6k
    clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_gstate_copy");
474
23.6k
    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
23.6k
    pnew->show_gstate =
482
23.6k
        (pgs->show_gstate == pgs ? pnew : NULL);
483
23.6k
    return pnew;
484
23.6k
}
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
0
{
497
0
    int code =
498
0
        gstate_copy(pto, pgs, copy_for_currentgstate, "gs_currentgstate");
499
500
0
    if (code >= 0)
501
0
        pto->view_clip = 0;
502
0
    return code;
503
0
}
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
1.49k
{
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
1.49k
    gs_gstate *saved_show = pgs->show_gstate;
515
1.49k
    int level = pgs->level;
516
1.49k
    gx_clip_path *view_clip = pgs->view_clip;
517
1.49k
    int code;
518
519
1.49k
    pgs->view_clip = 0;         /* prevent refcount decrementing */
520
1.49k
    code = gstate_copy(pgs, pfrom, copy_for_setgstate, "gs_setgstate");
521
1.49k
    if (code < 0)
522
0
        return code;
523
1.49k
    pgs->level = level;
524
1.49k
    pgs->view_clip = view_clip;
525
1.49k
    pgs->show_gstate =
526
1.49k
        (pgs->show_gstate == pfrom ? pgs : saved_show);
527
1.49k
    return 0;
528
1.49k
}
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
2.82k
{
536
2.82k
    return pgs->memory;
537
2.82k
}
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
4.48k
{
544
4.48k
    return pgs->saved;
545
4.48k
}
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
0
{
563
0
    gs_memory_t *memory = pgs->memory;
564
565
0
    pgs->memory = mem;
566
0
    return memory;
567
0
}
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
83
{
580
83
    gs_composite_t *    pct = 0;
581
83
    int                 code;
582
83
    gx_device *         dev = pgs->device;
583
83
    gx_device *         ovptdev;
584
585
83
    code = gs_create_overprint(&pct, pparams, pgs->memory);
586
83
    if (code >= 0) {
587
83
        code = dev_proc(dev, composite)( dev,
588
83
                                                   &ovptdev,
589
83
                                                   pct,
590
83
                                                   pgs,
591
83
                                                   pgs->memory,
592
83
                                                   NULL);
593
83
        if (code >= 0 || code == gs_error_handled){
594
83
            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
83
            code = 0;
600
83
        }
601
83
    }
602
83
    if (pct != 0)
603
83
        gs_free_object(pgs->memory, pct, "gs_gstate_update_overprint");
604
605
    /* the following hack handles devices that don't support compositors */
606
83
    if (code == gs_error_unknownerror && !pparams->retain_any_comps)
607
0
        code = 0;
608
83
    return code;
609
83
}
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
82
{
630
82
    const gs_color_space *  pcs = gs_currentcolorspace_inline(pgs);
631
82
    const gs_client_color * pcc = gs_currentcolor_inline(pgs);
632
82
    int                     code = 0;
633
634
82
    if (cs_num_components(pcs) < 0 && pcc->pattern != 0)
635
0
        code = pcc->pattern->type->procs.set_color(pcc, pgs);
636
82
    else {
637
82
        gx_device* dev = pgs->device;
638
82
        cmm_dev_profile_t* dev_profile;
639
82
        gs_color_space_index pcs_index = gs_color_space_get_index(pcs);
640
641
82
        dev_proc(dev, get_profile)(dev, &dev_profile);
642
82
        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
82
        if (dev_proc(dev, dev_spec_op)(dev, gxdso_pdf14_sep_device, NULL, 0) &&
650
82
            (dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE) &&
651
82
            (pcs_index == gs_color_space_index_DeviceN ||
652
0
             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
82
        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
82
        pgs->color[0].effective_opm = pgs->overprint_mode;
677
678
82
        if_debug2m(gs_debug_flag_overprint, pgs->memory,
679
82
            "[overprint] gs_do_set_overprint. Preset effective mode. pgs->color[0].effective_opm = %d pgs->color[1].effective_opm = %d\n",
680
82
            pgs->color[0].effective_opm, pgs->color[1].effective_opm);
681
682
82
        pcs->type->set_overprint(pcs, pgs);
683
82
    }
684
82
    return code;
685
82
}
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
11.1k
{
695
11.1k
    pgs->overprint = ovp;
696
11.1k
    pgs->stroke_overprint = ovp;
697
11.1k
}
698
699
/* currentoverprint */
700
bool
701
gs_currentoverprint(const gs_gstate * pgs)
702
5.59k
{
703
5.59k
    return pgs->overprint;
704
5.59k
}
705
706
/* setstrokeoverprint */
707
void
708
gs_setstrokeoverprint(gs_gstate * pgs, bool ovp)
709
2.46k
{
710
2.46k
    pgs->stroke_overprint = ovp;
711
2.46k
}
712
713
/* currentstrokeoverprint */
714
bool
715
gs_currentstrokeoverprint(const gs_gstate * pgs)
716
0
{
717
0
    return pgs->stroke_overprint;
718
0
}
719
720
/* setstrokeoverprint */
721
void
722
gs_setfilloverprint(gs_gstate * pgs, bool ovp)
723
2.46k
{
724
2.46k
    pgs->overprint = ovp;
725
2.46k
}
726
727
/* currentstrokeoverprint */
728
bool
729
gs_currentfilloverprint(const gs_gstate * pgs)
730
0
{
731
0
    return pgs->overprint;
732
0
}
733
734
/* setoverprintmode */
735
int
736
gs_setoverprintmode(gs_gstate * pgs, int mode)
737
14.0k
{
738
14.0k
    if (mode < 0 || mode > 1)
739
0
        return_error(gs_error_rangecheck);
740
14.0k
    pgs->overprint_mode = mode;
741
742
14.0k
    return 0;
743
14.0k
}
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
2.61M
{
764
2.61M
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
765
766
2.61M
    return libctx->core->CPSI_mode;
767
2.61M
}
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
2.03k
{
777
2.03k
    int scanconverter = gs_getscanconverter(pgs->memory);
778
2.03k
    if (scanconverter >= GS_SCANCONVERTER_EDGEBUFFER || (GS_SCANCONVERTER_DEFAULT_IS_EDGEBUFFER && scanconverter == GS_SCANCONVERTER_DEFAULT)) {
779
2.03k
        fixed adjust = (pgs->fill_adjust.x >= float2fixed(0.25) || pgs->fill_adjust.y >= float2fixed(0.25) ? fixed_half : 0);
780
2.03k
        pgs->fill_adjust.x = adjust;
781
2.03k
        pgs->fill_adjust.y = adjust;
782
2.03k
    }
783
2.03k
}
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
432k
{
799
432k
    gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem);
800
801
432k
    return libctx->core->scanconverter;
802
432k
}
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
13.2k
gs_setrenderingintent(gs_gstate *pgs, int ri) {
815
13.2k
    if (ri < 0 || ri > 3)
816
0
        return_error(gs_error_rangecheck);
817
13.2k
    pgs->renderingintent = ri;
818
13.2k
    return 0;
819
13.2k
}
820
821
/* currentrenderingintent */
822
int
823
gs_currentrenderingintent(const gs_gstate * pgs)
824
5.99k
{
825
5.99k
    return pgs->renderingintent;
826
5.99k
}
827
828
int
829
0
gs_setblackptcomp(gs_gstate *pgs, bool bkpt) {
830
0
    pgs->blackptcomp = bkpt;
831
0
    return 0;
832
0
}
833
834
/* currentrenderingintent */
835
bool
836
gs_currentblackptcomp(const gs_gstate * pgs)
837
0
{
838
0
    return pgs->blackptcomp;
839
0
}
840
841
/*
842
 * Reset most of the graphics state.
843
 */
844
int
845
gs_initgraphics(gs_gstate * pgs)
846
5.71k
{
847
5.71k
    int code;
848
5.71k
    const gs_gstate gstate_initial = {
849
5.71k
            gs_gstate_initial(1.0)
850
5.71k
        };
851
5.71k
    gs_matrix m;
852
5.71k
    gs_make_identity(&m);
853
854
5.71k
    gs_initmatrix(pgs);
855
5.71k
    if ((code = gs_newpath(pgs)) < 0 ||
856
5.71k
        (code = gs_initclip(pgs)) < 0 ||
857
5.71k
        (code = gs_setlinewidth(pgs, 1.0)) < 0 ||
858
5.71k
        (code = gs_setlinestartcap(pgs, gstate_initial.line_params.start_cap)) < 0 ||
859
5.71k
        (code = gs_setlineendcap(pgs, gstate_initial.line_params.end_cap)) < 0 ||
860
5.71k
        (code = gs_setlinedashcap(pgs, gstate_initial.line_params.dash_cap)) < 0 ||
861
5.71k
        (code = gs_setlinejoin(pgs, gstate_initial.line_params.join)) < 0 ||
862
5.71k
        (code = gs_setcurvejoin(pgs, gstate_initial.line_params.curve_join)) < 0 ||
863
5.71k
        (code = gs_setdash(pgs, (float *)0, 0, 0.0)) < 0 ||
864
5.71k
        (gs_setdashadapt(pgs, false),
865
5.71k
         (code = gs_setdotlength(pgs, 0.0, false))) < 0 ||
866
5.71k
        (code = gs_setdotorientation(pgs)) < 0 ||
867
5.71k
        (code = gs_setmiterlimit(pgs, gstate_initial.line_params.miter_limit)) < 0
868
5.71k
        )
869
0
        return code;
870
5.71k
    gs_init_rop(pgs);
871
    /* Initialize things so that gx_remap_color won't crash. */
872
5.71k
    if (pgs->icc_manager->default_gray == 0x00) {
873
683
        gs_color_space  *pcs1, *pcs2;
874
875
683
        pcs1 = gs_cspace_new_DeviceGray(pgs->memory);
876
683
        if (pcs1 == NULL)
877
0
            return_error(gs_error_unknownerror);
878
879
683
        if (pgs->color[0].color_space != NULL) {
880
0
            gs_setcolorspace(pgs, pcs1);
881
0
            rc_decrement_cs(pcs1, "gs_initgraphics");
882
683
        } else {
883
683
            pgs->color[0].color_space = pcs1;
884
683
            gs_setcolorspace(pgs, pcs1);
885
683
        }
886
683
        code = gx_set_dev_color(pgs);
887
683
        if (code < 0)
888
0
            return code;
889
890
683
        gs_swapcolors_quick(pgs); /* To color 1 */
891
892
683
        pcs2 = gs_cspace_new_DeviceGray(pgs->memory);
893
683
        if (pcs2 == NULL)
894
0
            return_error(gs_error_unknownerror);
895
896
683
        if (pgs->color[0].color_space != NULL) {
897
0
            gs_setcolorspace(pgs, pcs2);
898
0
            rc_decrement_cs(pcs2, "gs_initgraphics");
899
683
        } else {
900
683
            pgs->color[0].color_space = pcs2;
901
683
            gs_setcolorspace(pgs, pcs2);
902
683
        }
903
683
        code = gx_set_dev_color(pgs);
904
905
683
        gs_swapcolors_quick(pgs); /* To color 0 */
906
907
683
        if (code < 0)
908
0
            return code;
909
910
5.03k
    } else {
911
5.03k
        gs_color_space  *pcs1, *pcs2;
912
913
5.03k
        pcs1 = gs_cspace_new_ICC(pgs->memory, pgs, 1);
914
5.03k
        if (pcs1 == NULL)
915
0
            return_error(gs_error_unknownerror);
916
917
5.03k
        if (pgs->color[0].color_space != NULL) {
918
4.36k
            gs_setcolorspace(pgs, pcs1);
919
4.36k
            rc_decrement_cs(pcs1, "gs_initgraphics");
920
4.36k
        } else {
921
669
            pgs->color[0].color_space = pcs1;
922
669
            gs_setcolorspace(pgs, pcs1);
923
669
        }
924
5.03k
        code = gx_set_dev_color(pgs);
925
5.03k
        if (code < 0)
926
0
            return code;
927
928
5.03k
        gs_swapcolors_quick(pgs); /* To color 1 */
929
5.03k
        pcs2 = gs_cspace_new_ICC(pgs->memory, pgs, 1);
930
5.03k
        if (pcs2 == NULL)
931
0
            return_error(gs_error_unknownerror);
932
933
5.03k
        if (pgs->color[0].color_space != NULL) {
934
4.36k
            gs_setcolorspace(pgs, pcs2);
935
4.36k
            rc_decrement_cs(pcs2, "gs_initgraphics");
936
4.36k
        } else {
937
669
            pgs->color[0].color_space = pcs2;
938
669
            gs_setcolorspace(pgs, pcs2);
939
669
        }
940
5.03k
        code = gx_set_dev_color(pgs);
941
942
5.03k
        gs_swapcolors_quick(pgs); /* To color 0 */
943
944
5.03k
        if (code < 0)
945
0
            return code;
946
5.03k
    }
947
5.71k
    pgs->in_cachedevice = 0;
948
949
5.71k
    code = gs_settextspacing(pgs, (double)0.0);
950
5.71k
    if (code < 0)
951
0
        goto exit;
952
5.71k
    code = gs_settextleading(pgs, (double)0.0);
953
5.71k
    if (code < 0)
954
0
        goto exit;
955
956
5.71k
    gs_settextrenderingmode(pgs, 0);
957
958
5.71k
    code = gs_setwordspacing(pgs, (double)0.0);
959
5.71k
    if (code < 0)
960
0
        goto exit;
961
5.71k
    code = gs_settexthscaling(pgs, (double)100.0);
962
5.71k
    if (code < 0)
963
0
        goto exit;
964
965
5.71k
    gs_setaccuratecurves(pgs, true);
966
967
5.71k
    code = gs_setstrokeconstantalpha(pgs, 1.0);
968
5.71k
    if (code < 0)
969
0
        goto exit;
970
5.71k
    code = gs_setfillconstantalpha(pgs, 1.0);
971
5.71k
    if (code < 0)
972
0
        goto exit;
973
5.71k
    code = gs_setalphaisshape(pgs, 0);
974
5.71k
    if (code < 0)
975
0
        goto exit;
976
5.71k
    code = gs_setblendmode(pgs, BLEND_MODE_Compatible);
977
5.71k
    if (code < 0)
978
0
        goto exit;
979
5.71k
    code = gs_settextknockout(pgs, true);
980
5.71k
    if (code < 0)
981
0
        goto exit;
982
5.71k
    code = gs_setsmoothness(pgs, 0.02); /* Match gs code */
983
5.71k
    if (code < 0)
984
0
        goto exit;
985
986
5.71k
    code = gs_settextmatrix(pgs, &m);
987
5.71k
    if (code < 0)
988
0
        goto exit;
989
990
5.71k
    code = gs_settextlinematrix(pgs, &m);
991
5.71k
    if (code < 0)
992
0
        goto exit;
993
5.71k
exit:
994
5.71k
    return code;
995
5.71k
}
996
997
/* setfilladjust */
998
int
999
gs_setfilladjust(gs_gstate * pgs, double adjust_x, double adjust_y)
1000
2.03k
{
1001
2.03k
#define CLAMP_TO_HALF(v)\
1002
4.07k
    ((v) <= 0 ? fixed_0 : (v) >= 0.5 ? fixed_half : float2fixed(v));
1003
1004
2.03k
    pgs->fill_adjust.x = CLAMP_TO_HALF(adjust_x);
1005
2.03k
    pgs->fill_adjust.y = CLAMP_TO_HALF(adjust_y);
1006
1007
2.03k
    sanitize_fill_adjust(pgs);
1008
1009
2.03k
    return 0;
1010
2.03k
#undef CLAMP_TO_HALF
1011
2.03k
}
1012
1013
/* currentfilladjust */
1014
int
1015
gs_currentfilladjust(const gs_gstate * pgs, gs_point * adjust)
1016
9.30k
{
1017
9.30k
    adjust->x = fixed2float(pgs->fill_adjust.x);
1018
9.30k
    adjust->y = fixed2float(pgs->fill_adjust.y);
1019
9.30k
    return 0;
1020
9.30k
}
1021
1022
/* setlimitclamp */
1023
void
1024
gs_setlimitclamp(gs_gstate * pgs, bool clamp)
1025
2.70k
{
1026
2.70k
    pgs->clamp_coordinates = clamp;
1027
2.70k
}
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
11.0k
{
1040
11.0k
    pgs->text_rendering_mode = trm;
1041
11.0k
}
1042
1043
/* currenttextrenderingmode */
1044
uint
1045
gs_currenttextrenderingmode(const gs_gstate * pgs)
1046
899k
{
1047
899k
    return pgs->text_rendering_mode;
1048
899k
}
1049
1050
double
1051
gs_currenttextspacing(const gs_gstate *pgs)
1052
557k
{
1053
557k
    return pgs->textspacing;
1054
557k
}
1055
1056
int
1057
gs_settextspacing(gs_gstate *pgs, double Tc)
1058
32.1k
{
1059
32.1k
    int code = 0;
1060
32.1k
    gs_fixed_point dxy;
1061
1062
32.1k
    code = gs_distance_transform2fixed(&pgs->ctm, Tc, 1, &dxy);
1063
32.1k
    if (code < 0)
1064
1
        return code;
1065
1066
32.1k
    pgs->textspacing = (float)Tc;
1067
32.1k
    return 0;
1068
32.1k
}
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
20.5k
{
1079
20.5k
    pgs->textleading = (float)TL;
1080
20.5k
    return 0;
1081
20.5k
}
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
54
{
1092
54
    pgs->textrise = (float)Ts;
1093
54
    return 0;
1094
54
}
1095
1096
double
1097
gs_currentwordspacing(const gs_gstate *pgs)
1098
557k
{
1099
557k
    return pgs->wordspacing;
1100
557k
}
1101
1102
int
1103
gs_setwordspacing(gs_gstate *pgs, double Tw)
1104
8.36k
{
1105
8.36k
    pgs->wordspacing = (float)Tw;
1106
8.36k
    return 0;
1107
8.36k
}
1108
1109
int
1110
gs_settexthscaling(gs_gstate *pgs, double Tz)
1111
31.4k
{
1112
31.4k
    pgs->texthscaling = (float)Tz;
1113
31.4k
    return 0;
1114
31.4k
}
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
35.8k
{
1125
35.8k
    pgs->PDFfontsize = (float)Tf;
1126
35.8k
    return 0;
1127
35.8k
}
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
234k
{
1138
234k
    pgs->textlinematrix.xx = m->xx;
1139
234k
    pgs->textlinematrix.xy = m->xy;
1140
234k
    pgs->textlinematrix.yx = m->yx;
1141
234k
    pgs->textlinematrix.yy = m->yy;
1142
234k
    pgs->textlinematrix.tx = m->tx;
1143
234k
    pgs->textlinematrix.ty = m->ty;
1144
234k
    return 0;
1145
234k
}
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
234k
{
1161
234k
    pgs->textmatrix.xx = m->xx;
1162
234k
    pgs->textmatrix.xy = m->xy;
1163
234k
    pgs->textmatrix.yx = m->yx;
1164
234k
    pgs->textmatrix.yy = m->yy;
1165
234k
    pgs->textmatrix.tx = m->tx;
1166
234k
    pgs->textmatrix.ty = m->ty;
1167
234k
    return 0;
1168
234k
}
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
1.54M
{
1202
1.54M
    gs_free_object(mem, parts->color[1].dev_color, cname);
1203
1.54M
    gs_free_object(mem, parts->color[1].ccolor, cname);
1204
1.54M
    gs_free_object(mem, parts->color[0].dev_color, cname);
1205
1.54M
    gs_free_object(mem, parts->color[0].ccolor, cname);
1206
1.54M
    parts->color[1].dev_color = 0;
1207
1.54M
    parts->color[1].ccolor = 0;
1208
1.54M
    parts->color[0].dev_color = 0;
1209
1.54M
    parts->color[0].ccolor = 0;
1210
1.54M
    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
1.54M
    gx_cpath_free(parts->clip_path, cname);
1215
1.54M
    parts->clip_path = 0;
1216
1.54M
    if (parts->path) {
1217
775k
        gx_path_free(parts->path, cname);
1218
775k
        parts->path = 0;
1219
775k
    }
1220
1.54M
}
1221
1222
static inline void
1223
gstate_parts_init_dev_color(gx_device_color *dc)
1224
1.55M
{
1225
1.55M
    gx_device_color_type dct = dc->type;
1226
1.55M
    gs_graphics_type_tag_t gtt = dc->tag;
1227
1.55M
    memset(dc, 0x00, sizeof(gx_device_color));
1228
1.55M
    dc->type = dct;
1229
1.55M
    dc->tag = gtt;
1230
1.55M
}
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
775k
{
1237
775k
    gs_memory_t *path_mem = gstate_path_memory(mem);
1238
1239
775k
    parts->path =
1240
775k
        (shared ?
1241
774k
         gx_path_alloc_shared(shared->path, path_mem,
1242
774k
                              "gstate_alloc_parts(path)") :
1243
775k
         gx_path_alloc(path_mem, "gstate_alloc_parts(path)"));
1244
775k
    parts->clip_path =
1245
775k
        (shared ?
1246
774k
         gx_cpath_alloc_shared(shared->clip_path, mem,
1247
774k
                               "gstate_alloc_parts(clip_path)") :
1248
775k
         gx_cpath_alloc(mem, "gstate_alloc_parts(clip_path)"));
1249
775k
    if (!shared || shared->effective_clip_shared) {
1250
775k
        parts->effective_clip_path = parts->clip_path;
1251
775k
        parts->effective_clip_shared = true;
1252
775k
    } 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
775k
    parts->color[0].color_space = NULL;
1259
775k
    parts->color[1].color_space = NULL;
1260
775k
    parts->color[0].ccolor =
1261
775k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
1262
775k
    parts->color[1].ccolor =
1263
775k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, cname);
1264
775k
    parts->color[0].dev_color =
1265
775k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
1266
775k
    parts->color[1].dev_color =
1267
775k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, cname);
1268
775k
    if (parts->path == 0 || parts->clip_path == 0 ||
1269
775k
        parts->effective_clip_path == 0 ||
1270
775k
        parts->color[0].ccolor == 0 || parts->color[0].dev_color == 0 ||
1271
775k
        parts->color[1].ccolor == 0 || parts->color[1].dev_color == 0
1272
775k
        ) {
1273
0
        gstate_free_parts(parts, mem, cname);
1274
0
        return_error(gs_error_VMerror);
1275
0
    }
1276
775k
    gstate_parts_init_dev_color(parts->color[0].dev_color);
1277
775k
    gstate_parts_init_dev_color(parts->color[1].dev_color);
1278
775k
    return 0;
1279
775k
}
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
775k
{
1290
775k
    gs_gstate *pgs =
1291
775k
        gs_alloc_struct(mem, gs_gstate, &st_gs_gstate, cname);
1292
1293
775k
    if (pgs == NULL)
1294
0
        return NULL;
1295
775k
    memset(pgs, 0x00, sizeof(gs_gstate));
1296
775k
    if (gstate_alloc_parts(pgs, pfrom, mem, cname) < 0) {
1297
0
        gs_free_object(mem, pgs, cname);
1298
0
        return NULL;
1299
0
    }
1300
775k
    pgs->memory = mem;
1301
775k
    return pgs;
1302
775k
}
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
7.58k
{
1308
7.58k
    return gx_set_dash(dash, pfrom->line_params.dash.pattern,
1309
7.58k
                      pfrom->line_params.dash.pattern_size,
1310
7.58k
                      pfrom->line_params.dash.offset, mem);
1311
7.58k
}
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
774k
{
1325
774k
    gs_gstate *pgs = gstate_alloc(mem, cname, pfrom);
1326
774k
    void *pdata = NULL;
1327
1328
774k
    if (pgs == NULL)
1329
0
        return NULL;
1330
774k
    if (pfrom->client_data != NULL) {
1331
773k
        pdata = (*pfrom->client_procs.alloc) (mem);
1332
1333
773k
        if (pdata == NULL ||
1334
773k
            gstate_copy_client_data(pfrom, pdata, pfrom->client_data,
1335
773k
                                    reason) < 0)
1336
0
            goto failEarly;
1337
773k
    }
1338
    /* Copy the dash and dash pattern if necessary. */
1339
774k
    clone_data->dash = gs_currentlineparams_inline(pfrom)->dash;
1340
774k
    if (clone_data->dash.pattern) {
1341
7.56k
        int code;
1342
1343
7.56k
        clone_data->dash.pattern = NULL; /* Ensures a fresh allocation */
1344
7.56k
        code = gstate_copy_dash(mem, &clone_data->dash, pfrom);
1345
7.56k
        if (code < 0)
1346
0
            goto fail;
1347
7.56k
    }
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
774k
    GSTATE_ASSIGN_PARTS(&clone_data->parts, pgs);
1354
774k
    *pgs = *pfrom;
1355
774k
    pgs->client_data = pdata;
1356
1357
774k
    gs_gstate_copied(pgs);
1358
    /* Don't do anything to clip_stack. */
1359
1360
774k
    rc_increment(pgs->device);
1361
774k
    *clone_data->parts.color[0].ccolor    = *pgs->color[0].ccolor;
1362
774k
    *clone_data->parts.color[0].dev_color = *pgs->color[0].dev_color;
1363
774k
    *clone_data->parts.color[1].ccolor    = *pgs->color[1].ccolor;
1364
774k
    *clone_data->parts.color[1].dev_color = *pgs->color[1].dev_color;
1365
774k
    cs_adjust_counts_icc(pgs, 1);
1366
774k
    cs_adjust_swappedcounts_icc(pgs, 1);
1367
1368
774k
    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
750k
{
1389
750k
    gs_gstate_clone_data clone_data;
1390
750k
    gs_gstate *pgs = gstate_clone_core(pfrom, pfrom->memory, cname,
1391
750k
                                       &clone_data, copy_for_gsave);
1392
1393
750k
    if (pgs == NULL)
1394
0
        return NULL;
1395
1396
    /* Newly allocated parts go back into pfrom, not pgs! */
1397
750k
    GSTATE_ASSIGN_PARTS(pfrom, &clone_data.parts);
1398
750k
    gs_currentlineparams_inline(pfrom)->dash = clone_data.dash;
1399
1400
750k
    return pgs;
1401
750k
}
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
23.6k
{
1410
23.6k
    gs_gstate_clone_data clone_data;
1411
23.6k
    gs_gstate *pgs = gstate_clone_core(pfrom, mem, cname, &clone_data,
1412
23.6k
                                       copy_for_gstate);
1413
1414
23.6k
    if (pgs == NULL)
1415
0
        return NULL;
1416
23.6k
    GSTATE_ASSIGN_PARTS(pgs, &clone_data.parts);
1417
23.6k
    pgs->view_clip = NULL;
1418
23.6k
    gs_currentlineparams_inline(pgs)->dash = clone_data.dash;
1419
23.6k
    pgs->memory = mem;
1420
1421
23.6k
    return pgs;
1422
23.6k
}
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
1.57M
{
1429
1.57M
    gx_clip_stack_t *p = cs;
1430
1431
1.57M
    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
1.57M
}
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
775k
{
1445
775k
    gs_gstate *pgs = (gs_gstate *)vptr;
1446
775k
    (void)cmem; /* unused */
1447
1448
775k
    if (cmem == NULL)
1449
0
        return;     /* place for breakpoint */
1450
775k
    gstate_free_contents(pgs);
1451
775k
}
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
1.54M
{
1458
1.54M
    gs_memory_t *mem = pgs->memory;
1459
1.54M
    const char *const cname = "gstate_free_contents";
1460
1461
1.54M
    rc_decrement(pgs->device, cname);
1462
1.54M
    pgs->device = 0;
1463
1.54M
    clip_stack_rc_adjust(pgs->clip_stack, -1, cname);
1464
1.54M
    pgs->clip_stack = 0;
1465
1.54M
    if (pgs->view_clip != NULL && pgs->level == 0) {
1466
1.35k
        gx_cpath_free(pgs->view_clip, cname);
1467
1.35k
        pgs->view_clip = NULL;
1468
1.35k
    }
1469
1.54M
    if (pgs->client_data != 0)
1470
774k
        (*pgs->client_procs.free) (pgs->client_data, mem, pgs);
1471
1.54M
    pgs->client_data = 0;
1472
1.54M
    cs_adjust_counts_icc(pgs, -1);
1473
1.54M
    cs_adjust_swappedcounts_icc(pgs, -1);
1474
1.54M
    pgs->color[0].color_space = 0;
1475
1.54M
    pgs->color[1].color_space = 0;
1476
1.54M
    gs_free_object(mem, pgs->line_params.dash.pattern, cname);
1477
1.54M
    pgs->line_params.dash.pattern = 0;
1478
1.54M
    gstate_free_parts(pgs, mem, cname);     /* this also clears pointers to freed elements */
1479
1.54M
    gs_gstate_release(pgs);
1480
1.54M
}
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
1.49k
{
1487
1.49k
    gs_gstate_parts parts;
1488
1489
1.49k
    GSTATE_ASSIGN_PARTS(&parts, pto);
1490
    /* Copy the dash pattern if necessary. */
1491
1.49k
    if (pfrom->line_params.dash.pattern || pto->line_params.dash.pattern) {
1492
21
        int code = gstate_copy_dash(pto->memory,
1493
21
                             &(gs_currentlineparams_inline(pto)->dash), pfrom);
1494
1495
21
        if (code < 0)
1496
0
            return code;
1497
21
    }
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
1.49k
    cs_adjust_counts_icc(pto, -1);
1505
1.49k
    cs_adjust_swappedcounts_icc(pto, -1);
1506
1.49k
    gx_path_assign_preserve(pto->path, pfrom->path);
1507
1.49k
    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
1.49k
    if (pfrom->effective_clip_shared) {
1513
        /*
1514
         * pfrom->effective_clip_path is either pfrom->view_clip or
1515
         * pfrom->clip_path.
1516
         */
1517
1.49k
        parts.effective_clip_path =
1518
1.49k
            (pfrom->effective_clip_path == pfrom->view_clip ?
1519
1.49k
             pto->view_clip : parts.clip_path);
1520
1.49k
    } else
1521
0
        gx_cpath_assign_preserve(pto->effective_clip_path,
1522
0
                                 pfrom->effective_clip_path);
1523
1.49k
    *parts.color[0].ccolor    = *pfrom->color[0].ccolor;
1524
1.49k
    *parts.color[0].dev_color = *pfrom->color[0].dev_color;
1525
1.49k
    *parts.color[1].ccolor    = *pfrom->color[1].ccolor;
1526
1.49k
    *parts.color[1].dev_color = *pfrom->color[1].dev_color;
1527
    /* Handle references from gstate object. */
1528
1.49k
    rc_pre_assign(pto->device, pfrom->device, cname);
1529
1.49k
    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
1.49k
    {
1534
1.49k
        struct gx_pattern_cache_s *pcache = pto->pattern_cache;
1535
1.49k
        void *pdata = pto->client_data;
1536
1.49k
        gs_memory_t *mem = pto->memory;
1537
1.49k
        gs_gstate *saved = pto->saved;
1538
1.49k
        float *pattern = pto->line_params.dash.pattern;
1539
1540
1.49k
        gs_gstate_pre_assign(pto, (const gs_gstate *)pfrom);
1541
1.49k
        *pto = *pfrom;
1542
1.49k
        pto->client_data = pdata;
1543
1.49k
        pto->memory = mem;
1544
1.49k
        pto->saved = saved;
1545
1.49k
        pto->line_params.dash.pattern = pattern;
1546
1.49k
        if (pto->pattern_cache == 0)
1547
0
            pto->pattern_cache = pcache;
1548
1.49k
        if (pfrom->client_data != 0) {
1549
            /* We need to break 'const' here. */
1550
1.43k
            gstate_copy_client_data((gs_gstate *) pfrom, pdata,
1551
1.43k
                                    pfrom->client_data, reason);
1552
1.43k
        }
1553
1.49k
    }
1554
1.49k
    GSTATE_ASSIGN_PARTS(pto, &parts);
1555
1.49k
    cs_adjust_counts_icc(pto, 1);
1556
1.49k
    cs_adjust_swappedcounts_icc(pto, 1);
1557
1.49k
    pto->show_gstate =
1558
1.49k
        (pfrom->show_gstate == pfrom ? pto : 0);
1559
1.49k
    return 0;
1560
1.49k
}
1561
1562
/* Accessories. */
1563
gs_id gx_get_clip_path_id(gs_gstate *pgs)
1564
0
{
1565
0
    return pgs->clip_path->id;
1566
0
}
1567
1568
void gs_swapcolors_quick(const gs_gstate *cpgs)
1569
1.00M
{
1570
1.00M
    union {
1571
1.00M
        const gs_gstate *cpgs;
1572
1.00M
        gs_gstate *pgs;
1573
1.00M
    } const_breaker;
1574
1.00M
    gs_gstate *pgs;
1575
1.00M
    struct gx_cie_joint_caches_s *tmp_cie;
1576
1.00M
    gs_devicen_color_map          tmp_ccm;
1577
1.00M
    gs_client_color              *tmp_cc;
1578
1.00M
    int                           tmp;
1579
1.00M
    gx_device_color              *tmp_dc;
1580
1.00M
    gs_color_space               *tmp_cs;
1581
1582
    /* Break const just once, neatly, here rather than
1583
     * hackily in every caller. */
1584
1.00M
    const_breaker.cpgs = cpgs;
1585
1.00M
    pgs = const_breaker.pgs;
1586
1587
1.00M
    tmp_cc               = pgs->color[0].ccolor;
1588
1.00M
    pgs->color[0].ccolor = pgs->color[1].ccolor;
1589
1.00M
    pgs->color[1].ccolor = tmp_cc;
1590
1591
1.00M
    tmp_dc                  = pgs->color[0].dev_color;
1592
1.00M
    pgs->color[0].dev_color = pgs->color[1].dev_color;
1593
1.00M
    pgs->color[1].dev_color = tmp_dc;
1594
1595
1.00M
    tmp_cs                    = pgs->color[0].color_space;
1596
1.00M
    pgs->color[0].color_space = pgs->color[1].color_space;
1597
1.00M
    pgs->color[1].color_space = tmp_cs;
1598
1599
    /* Overprint and effective_op vary with stroke/fill and cs */
1600
1.00M
    tmp                         = pgs->color[0].effective_opm;
1601
1.00M
    pgs->color[0].effective_opm = pgs->color[1].effective_opm;
1602
1.00M
    pgs->color[1].effective_opm = tmp;
1603
1604
    /* Swap the bits of the gs_gstate that depend on the current color */
1605
1.00M
    tmp_cie                   = pgs->cie_joint_caches;
1606
1.00M
    pgs->cie_joint_caches     = pgs->cie_joint_caches_alt;
1607
1.00M
    pgs->cie_joint_caches_alt = tmp_cie;
1608
1609
1.00M
    tmp_ccm                      = pgs->color_component_map;
1610
1.00M
    pgs->color_component_map     = pgs->color_component_map_alt;
1611
1.00M
    pgs->color_component_map_alt = tmp_ccm;
1612
1613
1.00M
    pgs->is_fill_color = !(pgs->is_fill_color); /* used by overprint for fill_stroke */
1614
1.00M
}