Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1993, 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: gspcolor.c,v 1.14 2004/08/04 19:36:12 stefan Exp $ */
18
/* Pattern color operators and procedures for Ghostscript library */
19
#include "math_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gsrop.h"
23
#include "gsstruct.h"
24
#include "gsutil.h"		/* for gs_next_ids */
25
#include "gxarith.h"
26
#include "gxfixed.h"
27
#include "gxmatrix.h"
28
#include "gxcoord.h"		/* for gs_concat, gx_tr'_to_fixed */
29
#include "gxcspace.h"		/* for gscolor2.h */
30
#include "gxcolor2.h"
31
#include "gxdcolor.h"
32
#include "gxdevice.h"
33
#include "gxdevmem.h"
34
#include "gxclip2.h"
35
#include "gspath.h"
36
#include "gxpath.h"
37
#include "gxpcolor.h"
38
#include "gzstate.h"
39
#include "gsimage.h"
40
#include "gsiparm4.h"
41
#include "stream.h"
42
 
43
/* GC descriptors */
44
public_st_pattern_template();
45
public_st_pattern_instance();
46
 
47
/* Define the Pattern color space. */
48
gs_private_st_composite(st_color_space_Pattern, gs_paint_color_space,
49
     "gs_color_space_Pattern", cs_Pattern_enum_ptrs, cs_Pattern_reloc_ptrs);
50
private cs_proc_num_components(gx_num_components_Pattern);
51
private cs_proc_base_space(gx_base_space_Pattern);
52
private cs_proc_remap_color(gx_remap_Pattern);
53
private cs_proc_init_color(gx_init_Pattern);
54
private cs_proc_restrict_color(gx_restrict_Pattern);
55
private cs_proc_install_cspace(gx_install_Pattern);
56
private cs_proc_set_overprint(gx_set_overprint_Pattern);
57
private cs_proc_adjust_cspace_count(gx_adjust_cspace_Pattern);
58
private cs_proc_adjust_color_count(gx_adjust_color_Pattern);
59
private cs_proc_serialize(gx_serialize_Pattern);
60
const gs_color_space_type gs_color_space_type_Pattern = {
61
    gs_color_space_index_Pattern, false, false,
62
    &st_color_space_Pattern, gx_num_components_Pattern,
63
    gx_base_space_Pattern,
64
    gx_init_Pattern, gx_restrict_Pattern,
65
    gx_no_concrete_space,
66
    gx_no_concretize_color, NULL,
67
    gx_remap_Pattern, gx_install_Pattern,
68
    gx_set_overprint_Pattern,
69
    gx_adjust_cspace_Pattern, gx_adjust_color_Pattern,
70
    gx_serialize_Pattern,
71
    gx_cspace_no_linear
72
};
73
 
74
/* Initialize a generic pattern template. */
75
void
76
gs_pattern_common_init(gs_pattern_template_t * ppat,
77
		       const gs_pattern_type_t *type)
78
{
79
    ppat->type = type;
80
    ppat->PatternType = type->PatternType;
81
    uid_set_invalid(&ppat->uid);
82
    ppat->client_data = 0;	/* for GC */
83
}
84
 
85
/* Generic makepattern */
86
int
87
gs_make_pattern(gs_client_color * pcc, const gs_pattern_template_t * pcp,
88
		const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem)
89
{
90
    return pcp->type->procs.make_pattern(pcc, pcp, pmat, pgs, mem);
91
}
92
 
93
/*
94
 * Do the generic work for makepattern: allocate the instance and the
95
 * saved graphics state, and fill in the common members.
96
 */
97
int
98
gs_make_pattern_common(gs_client_color *pcc,
99
		       const gs_pattern_template_t *ptemp,
100
		       const gs_matrix *pmat, gs_state *pgs, gs_memory_t *mem,
101
		       gs_memory_type_ptr_t pstype)
102
{
103
    gs_pattern_instance_t *pinst;
104
    gs_state *saved;
105
 
106
    if (mem == 0)
107
	mem = gs_state_memory(pgs);
108
    rc_alloc_struct_1(pinst, gs_pattern_instance_t, pstype, mem,
109
		      return_error(gs_error_VMerror),
110
		      "gs_make_pattern_common");
111
    pinst->rc.free = rc_free_pattern_instance;
112
    pinst->type = ptemp->type;
113
    saved = gs_state_copy(pgs, mem);
114
    if (saved == 0) {
115
	gs_free_object(mem, pinst, "gs_make_pattern_common");
116
	return_error(gs_error_VMerror);
117
    }
118
    gs_concat(saved, pmat);
119
    gs_newpath(saved);
120
    pinst->saved = saved;
121
    pcc->pattern = pinst;
122
    pcc->pattern->pattern_id = gs_next_ids(mem, 1);
123
    return 0;
124
}
125
 
126
/* Free the saved gstate when freeing a Pattern instance. */
127
void
128
rc_free_pattern_instance(gs_memory_t * mem, void *pinst_void,
129
			 client_name_t cname)
130
{
131
    gs_pattern_instance_t *pinst = pinst_void;
132
 
133
    gs_state_free(pinst->saved);
134
    rc_free_struct_only(mem, pinst_void, cname);
135
}
136
 
137
/* setpattern */
138
int
139
gs_setpattern(gs_state * pgs, const gs_client_color * pcc)
140
{
141
    int code = gs_setpatternspace(pgs);
142
 
143
    if (code < 0)
144
	return code;
145
    return gs_setcolor(pgs, pcc);
146
}
147
 
148
/* setpatternspace */
149
/* This does all the work of setpattern except for the final setcolor. */
150
int
151
gs_setpatternspace(gs_state * pgs)
152
{
153
    int code = 0;
154
 
155
    if (pgs->in_cachedevice)
156
	return_error(gs_error_undefined);
157
    if (pgs->color_space->type->index != gs_color_space_index_Pattern) {
158
	gs_color_space cs;
159
 
160
	gs_cspace_init(&cs, &gs_color_space_type_Pattern, pgs->memory, false);
161
	/**************** base_space SETTING IS WRONG ****************/
162
	cs.params.pattern.base_space =
163
	    *(gs_paint_color_space *) pgs->color_space;
164
	cs.params.pattern.has_base_space = true;
165
	*pgs->color_space = cs;
166
	cs_full_init_color(pgs->ccolor, &cs);
167
	gx_unset_dev_color(pgs);
168
    }
169
    return code;
170
}
171
 
172
/*
173
 * Adjust the reference count of a pattern. This is intended to support
174
 * applications (such as PCL) which maintain client colors outside of the
175
 * graphic state. Since the pattern instance structure is opaque to these
176
 * applications, they need some way to release or retain the instances as
177
 * needed.
178
 */
179
void
180
gs_pattern_reference(gs_client_color * pcc, int delta)
181
{
182
    if (pcc->pattern != 0)
183
        rc_adjust(pcc->pattern, delta, "gs_pattern_reference");
184
}
185
 
186
/* getpattern */
187
/* This is only intended for the benefit of pattern PaintProcs. */
188
const gs_pattern_template_t *
189
gs_get_pattern(const gs_client_color * pcc)
190
{
191
    const gs_pattern_instance_t *pinst = pcc->pattern;
192
 
193
    return (pinst == 0 ? 0 : pinst->type->procs.get_pattern(pinst));
194
}
195
 
196
/*
197
 * Get the number of components in a Pattern color.
198
 * For backward compatibility, and to distinguish Pattern color spaces
199
 * from all others, we negate the result.
200
 */
201
private int
202
gx_num_components_Pattern(const gs_color_space * pcs)
203
{
204
    return
205
	(pcs->params.pattern.has_base_space ?
206
	 -1 - cs_num_components((const gs_color_space *)
207
				&(pcs->params.pattern.base_space)) :
208
	 -1 /* Pattern dictionary only */ );
209
}
210
 
211
/* Get the base space of a Pattern color space. */
212
private const gs_color_space *
213
gx_base_space_Pattern(const gs_color_space * pcs)
214
{
215
    return
216
	(pcs->params.pattern.has_base_space ?
217
	 (const gs_color_space *)&(pcs->params.pattern.base_space) :
218
	 NULL);
219
}
220
 
221
/* Remap a Pattern color. */
222
private int
223
gx_remap_Pattern(const gs_client_color * pc, const gs_color_space * pcs,
224
		 gx_device_color * pdc, const gs_imager_state * pis,
225
		 gx_device * dev, gs_color_select_t select)
226
{
227
    if (pc->pattern == 0) {
228
        pdc->ccolor_valid = false;
229
	color_set_null_pattern(pdc);
230
	return 0;
231
    }
232
    return
233
	pc->pattern->type->procs.remap_color(pc, pcs, pdc, pis, dev, select);
234
}
235
 
236
/* Initialize a Pattern color. */
237
private void
238
gx_init_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
239
{
240
    if (pcs->params.pattern.has_base_space) {
241
	const gs_color_space *pbcs =
242
	(const gs_color_space *)&pcs->params.pattern.base_space;
243
 
244
	cs_init_color(pcc, pbcs);
245
    }
246
    /*pcc->pattern = 0; *//* cs_full_init_color handles this */
247
}
248
 
249
/* Force a Pattern color into legal range. */
250
/* Note that if the pattern is uncolored (PaintType = 2), */
251
/* the color space must have a base space: we check this here only */
252
/* to prevent accessing uninitialized data, but if there is no base space, */
253
/* it is an error that we count on being detected elsewhere. */
254
private void
255
gx_restrict_Pattern(gs_client_color * pcc, const gs_color_space * pcs)
256
{
257
    /* We need a special check for the null pattern. */
258
    if (pcc->pattern &&
259
	pcc->pattern->type->procs.uses_base_space(gs_get_pattern(pcc)) &&
260
	pcs->params.pattern.has_base_space
261
	) {
262
	const gs_color_space *pbcs =
263
	    (const gs_color_space *)&pcs->params.pattern.base_space;
264
 
265
	(*pbcs->type->restrict_color) (pcc, pbcs);
266
    }
267
}
268
 
269
/* Install a Pattern color space. */
270
private int
271
gx_install_Pattern(const gs_color_space * pcs, gs_state * pgs)
272
{
273
    if (!pcs->params.pattern.has_base_space)
274
	return 0;
275
    return (*pcs->params.pattern.base_space.type->install_cspace)
276
	((const gs_color_space *) & pcs->params.pattern.base_space, pgs);
277
}
278
 
279
/*
280
 * Set the overprint compositor for a Pattern color space. This does nothing;
281
 * for patterns the overprint compositor is set at set_device_color time.
282
*/
283
private int
284
gx_set_overprint_Pattern(const gs_color_space * pcs, gs_state * pgs)
285
{
286
    return 0;
287
}
288
 
289
/* Adjust the reference counts for Pattern color spaces or colors. */
290
private void
291
gx_adjust_cspace_Pattern(const gs_color_space * pcs, int delta)
292
{
293
    if (pcs->params.pattern.has_base_space)
294
	(*pcs->params.pattern.base_space.type->adjust_cspace_count)
295
	    ((const gs_color_space *)&pcs->params.pattern.base_space, delta);
296
}
297
 
298
private void
299
gx_adjust_color_Pattern(const gs_client_color * pcc,
300
			const gs_color_space * pcs, int delta)
301
{
302
    gs_pattern_instance_t *pinst = pcc->pattern;
303
 
304
    rc_adjust_only(pinst, delta, "gx_adjust_color_Pattern");
305
    if (pcs && pcs->params.pattern.has_base_space)
306
	(*pcs->params.pattern.base_space.type->adjust_color_count)
307
	    (pcc, (const gs_color_space *)&pcs->params.pattern.base_space,
308
	     delta);
309
}
310
 
311
/* GC procedures */
312
 
313
private 
314
ENUM_PTRS_BEGIN_PROC(cs_Pattern_enum_ptrs)
315
{
316
    EV_CONST gs_color_space *const pcs = vptr;
317
 
318
    if (!pcs->params.pattern.has_base_space)
319
	return 0;
320
    return ENUM_USING(*pcs->params.pattern.base_space.type->stype,
321
		      &pcs->params.pattern.base_space,
322
		      sizeof(pcs->params.pattern.base_space), index);
323
}
324
ENUM_PTRS_END_PROC
325
private RELOC_PTRS_WITH(cs_Pattern_reloc_ptrs, gs_color_space *pcs)
326
{
327
    if (!pcs->params.pattern.has_base_space)
328
	return;
329
    RELOC_USING(*pcs->params.pattern.base_space.type->stype,
330
		&pcs->params.pattern.base_space,
331
		sizeof(gs_paint_color_space));
332
}
333
RELOC_PTRS_END
334
 
335
/* ---------------- Serialization. -------------------------------- */
336
 
337
private int 
338
gx_serialize_Pattern(const gs_color_space * pcs, stream * s)
339
{
340
    const gs_pattern_params * p = &pcs->params.pattern;
341
    uint n;
342
    int code = gx_serialize_cspace_type(pcs, s);
343
 
344
    if (code < 0)
345
	return code;
346
    code = sputs(s, (byte *)&p->has_base_space, sizeof(p->has_base_space), &n);
347
    if (code < 0)
348
	return code;
349
    if (!p->has_base_space)
350
	return 0;
351
    return cs_serialize((const gs_color_space *)&p->base_space, s);
352
}