2 |
- |
1 |
/* Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved.
|
|
|
2 |
|
|
|
3 |
This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
implied.
|
|
|
5 |
|
|
|
6 |
This software is distributed under license and may not be copied,
|
|
|
7 |
modified or distributed except as expressly authorized under the terms
|
|
|
8 |
of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
|
|
|
10 |
For more information about licensing, please refer to
|
|
|
11 |
http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
*/
|
|
|
16 |
|
|
|
17 |
/* $Id: gsistate.c,v 1.12 2005/08/30 06:38:44 igor Exp $ */
|
|
|
18 |
/* Imager state housekeeping */
|
|
|
19 |
#include "gx.h"
|
|
|
20 |
#include "gserrors.h"
|
|
|
21 |
#include "gscspace.h"
|
|
|
22 |
#include "gscie.h"
|
|
|
23 |
#include "gsstruct.h"
|
|
|
24 |
#include "gsutil.h" /* for gs_next_ids */
|
|
|
25 |
#include "gxbitmap.h"
|
|
|
26 |
#include "gxcmap.h"
|
|
|
27 |
#include "gxdht.h"
|
|
|
28 |
#include "gxistate.h"
|
|
|
29 |
#include "gzht.h"
|
|
|
30 |
#include "gzline.h"
|
|
|
31 |
#include "gxfmap.h"
|
|
|
32 |
|
|
|
33 |
/******************************************************************************
|
|
|
34 |
* See gsstate.c for a discussion of graphics/imager state memory management. *
|
|
|
35 |
******************************************************************************/
|
|
|
36 |
|
|
|
37 |
/* Imported values */
|
|
|
38 |
/* The following should include a 'const', but for some reason */
|
|
|
39 |
/* the Watcom compiler won't accept it, even though it happily accepts */
|
|
|
40 |
/* the same construct everywhere else. */
|
|
|
41 |
extern /*const*/ gx_color_map_procs *const cmap_procs_default;
|
|
|
42 |
|
|
|
43 |
/* GC procedures for gx_line_params */
|
|
|
44 |
private
|
|
|
45 |
ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0;
|
|
|
46 |
case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ?
|
|
|
47 |
NULL : plp->dash.pattern));
|
|
|
48 |
ENUM_PTRS_END
|
|
|
49 |
private RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp)
|
|
|
50 |
{
|
|
|
51 |
if (plp->dash.pattern_size)
|
|
|
52 |
RELOC_VAR(plp->dash.pattern);
|
|
|
53 |
} RELOC_PTRS_END
|
|
|
54 |
private_st_line_params();
|
|
|
55 |
|
|
|
56 |
/*
|
|
|
57 |
* GC procedures for gs_imager_state
|
|
|
58 |
*
|
|
|
59 |
* See comments in gixstate.h before the definition of gs_cr_state_do_rc and
|
|
|
60 |
* st_cr_state_num_ptrs for an explanation about why the effective_transfer
|
|
|
61 |
* pointers are handled in this manner.
|
|
|
62 |
*/
|
|
|
63 |
public_st_imager_state();
|
|
|
64 |
private
|
|
|
65 |
ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
|
|
|
66 |
ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
|
|
|
67 |
ENUM_PTR(0, gs_imager_state, client_data);
|
|
|
68 |
ENUM_PTR(1, gs_imager_state, opacity.mask);
|
|
|
69 |
ENUM_PTR(2, gs_imager_state, shape.mask);
|
|
|
70 |
ENUM_PTR(3, gs_imager_state, transparency_stack);
|
|
|
71 |
#define E1(i,elt) ENUM_PTR(i+4,gs_imager_state,elt);
|
|
|
72 |
gs_cr_state_do_ptrs(E1)
|
|
|
73 |
#undef E1
|
|
|
74 |
ENUM_PTRS_END
|
|
|
75 |
private RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
|
|
|
76 |
{
|
|
|
77 |
RELOC_SUPER(gs_imager_state, st_line_params, line_params);
|
|
|
78 |
RELOC_PTR(gs_imager_state, client_data);
|
|
|
79 |
RELOC_PTR(gs_imager_state, opacity.mask);
|
|
|
80 |
RELOC_PTR(gs_imager_state, shape.mask);
|
|
|
81 |
RELOC_PTR(gs_imager_state, transparency_stack);
|
|
|
82 |
#define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
|
|
|
83 |
gs_cr_state_do_ptrs(R1)
|
|
|
84 |
#undef R1
|
|
|
85 |
{
|
|
|
86 |
int i = GX_DEVICE_COLOR_MAX_COMPONENTS - 1;
|
|
|
87 |
|
|
|
88 |
for (; i >= 0; i--)
|
|
|
89 |
RELOC_PTR(gs_imager_state, effective_transfer[i]);
|
|
|
90 |
}
|
|
|
91 |
} RELOC_PTRS_END
|
|
|
92 |
|
|
|
93 |
|
|
|
94 |
/* Initialize an imager state, other than the parts covered by */
|
|
|
95 |
/* gs_imager_state_initial. */
|
|
|
96 |
int
|
|
|
97 |
gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
|
|
|
98 |
{
|
|
|
99 |
int i;
|
|
|
100 |
pis->memory = mem;
|
|
|
101 |
pis->client_data = 0;
|
|
|
102 |
pis->opacity.mask = 0;
|
|
|
103 |
pis->shape.mask = 0;
|
|
|
104 |
pis->transparency_stack = 0;
|
|
|
105 |
/* Color rendering state */
|
|
|
106 |
pis->halftone = 0;
|
|
|
107 |
{
|
|
|
108 |
int i;
|
|
|
109 |
|
|
|
110 |
for (i = 0; i < gs_color_select_count; ++i)
|
|
|
111 |
pis->screen_phase[i].x = pis->screen_phase[i].y = 0;
|
|
|
112 |
}
|
|
|
113 |
pis->dev_ht = 0;
|
|
|
114 |
pis->cie_render = 0;
|
|
|
115 |
pis->black_generation = 0;
|
|
|
116 |
pis->undercolor_removal = 0;
|
|
|
117 |
/* Allocate an initial transfer map. */
|
|
|
118 |
rc_alloc_struct_n(pis->set_transfer.gray,
|
|
|
119 |
gx_transfer_map, &st_transfer_map,
|
|
|
120 |
mem, return_error(gs_error_VMerror),
|
|
|
121 |
"gs_imager_state_init(transfer)", 1);
|
|
|
122 |
pis->set_transfer.gray->proc = gs_identity_transfer;
|
|
|
123 |
pis->set_transfer.gray->id = gs_next_ids(pis->memory, 1);
|
|
|
124 |
pis->set_transfer.gray->values[0] = frac_0;
|
|
|
125 |
pis->set_transfer.red =
|
|
|
126 |
pis->set_transfer.green =
|
|
|
127 |
pis->set_transfer.blue = NULL;
|
|
|
128 |
for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
|
|
|
129 |
pis->effective_transfer[i] = pis->set_transfer.gray;
|
|
|
130 |
pis->cie_joint_caches = NULL;
|
|
|
131 |
pis->cmap_procs = cmap_procs_default;
|
|
|
132 |
pis->pattern_cache = NULL;
|
|
|
133 |
pis->have_pattern_streams = false;
|
|
|
134 |
return 0;
|
|
|
135 |
}
|
|
|
136 |
|
|
|
137 |
/*
|
|
|
138 |
* Make a temporary copy of a gs_imager_state. Note that this does not
|
|
|
139 |
* do all the necessary reference counting, etc. However, it does
|
|
|
140 |
* clear out the transparency stack in the destination.
|
|
|
141 |
*/
|
|
|
142 |
gs_imager_state *
|
|
|
143 |
gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem)
|
|
|
144 |
{
|
|
|
145 |
gs_imager_state *pis_copy =
|
|
|
146 |
gs_alloc_struct(mem, gs_imager_state, &st_imager_state,
|
|
|
147 |
"gs_imager_state_copy");
|
|
|
148 |
|
|
|
149 |
if (pis_copy) {
|
|
|
150 |
*pis_copy = *pis;
|
|
|
151 |
pis_copy->transparency_stack = 0;
|
|
|
152 |
}
|
|
|
153 |
return pis_copy;
|
|
|
154 |
}
|
|
|
155 |
|
|
|
156 |
/* Increment reference counts to note that an imager state has been copied. */
|
|
|
157 |
void
|
|
|
158 |
gs_imager_state_copied(gs_imager_state * pis)
|
|
|
159 |
{
|
|
|
160 |
rc_increment(pis->opacity.mask);
|
|
|
161 |
rc_increment(pis->shape.mask);
|
|
|
162 |
rc_increment(pis->halftone);
|
|
|
163 |
rc_increment(pis->dev_ht);
|
|
|
164 |
rc_increment(pis->cie_render);
|
|
|
165 |
rc_increment(pis->black_generation);
|
|
|
166 |
rc_increment(pis->undercolor_removal);
|
|
|
167 |
rc_increment(pis->set_transfer.gray);
|
|
|
168 |
rc_increment(pis->set_transfer.red);
|
|
|
169 |
rc_increment(pis->set_transfer.green);
|
|
|
170 |
rc_increment(pis->set_transfer.blue);
|
|
|
171 |
rc_increment(pis->cie_joint_caches);
|
|
|
172 |
}
|
|
|
173 |
|
|
|
174 |
/* Adjust reference counts before assigning one imager state to another. */
|
|
|
175 |
void
|
|
|
176 |
gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom)
|
|
|
177 |
{
|
|
|
178 |
const char *const cname = "gs_imager_state_pre_assign";
|
|
|
179 |
|
|
|
180 |
#define RCCOPY(element)\
|
|
|
181 |
rc_pre_assign(pto->element, pfrom->element, cname)
|
|
|
182 |
|
|
|
183 |
RCCOPY(cie_joint_caches);
|
|
|
184 |
RCCOPY(set_transfer.blue);
|
|
|
185 |
RCCOPY(set_transfer.green);
|
|
|
186 |
RCCOPY(set_transfer.red);
|
|
|
187 |
RCCOPY(set_transfer.gray);
|
|
|
188 |
RCCOPY(undercolor_removal);
|
|
|
189 |
RCCOPY(black_generation);
|
|
|
190 |
RCCOPY(cie_render);
|
|
|
191 |
RCCOPY(dev_ht);
|
|
|
192 |
RCCOPY(halftone);
|
|
|
193 |
RCCOPY(shape.mask);
|
|
|
194 |
RCCOPY(opacity.mask);
|
|
|
195 |
#undef RCCOPY
|
|
|
196 |
}
|
|
|
197 |
|
|
|
198 |
/* Release an imager state. */
|
|
|
199 |
void
|
|
|
200 |
gs_imager_state_release(gs_imager_state * pis)
|
|
|
201 |
{
|
|
|
202 |
const char *const cname = "gs_imager_state_release";
|
|
|
203 |
gx_device_halftone *pdht = pis->dev_ht;
|
|
|
204 |
|
|
|
205 |
#define RCDECR(element)\
|
|
|
206 |
rc_decrement(pis->element, cname)
|
|
|
207 |
|
|
|
208 |
RCDECR(cie_joint_caches);
|
|
|
209 |
RCDECR(set_transfer.gray);
|
|
|
210 |
RCDECR(set_transfer.blue);
|
|
|
211 |
RCDECR(set_transfer.green);
|
|
|
212 |
RCDECR(set_transfer.red);
|
|
|
213 |
RCDECR(undercolor_removal);
|
|
|
214 |
RCDECR(black_generation);
|
|
|
215 |
RCDECR(cie_render);
|
|
|
216 |
/*
|
|
|
217 |
* If we're going to free the device halftone, make sure we free the
|
|
|
218 |
* dependent structures as well.
|
|
|
219 |
*/
|
|
|
220 |
if (pdht != 0 && pdht->rc.ref_count == 1) {
|
|
|
221 |
gx_device_halftone_release(pdht, pdht->rc.memory);
|
|
|
222 |
}
|
|
|
223 |
RCDECR(dev_ht);
|
|
|
224 |
RCDECR(halftone);
|
|
|
225 |
RCDECR(shape.mask);
|
|
|
226 |
RCDECR(opacity.mask);
|
|
|
227 |
#undef RCDECR
|
|
|
228 |
}
|