Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/gs/src/ztrans.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 2000-2002 artofcode LLC.  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: ztrans.c,v 1.28 2005/10/04 06:30:02 ray Exp $ */
18
/* Transparency operators */
19
#include "string_.h"
20
#include "memory_.h"
21
#include "ghost.h"
22
#include "oper.h"
23
#include "gscspace.h"		/* for gscolor2.h */
24
#include "gscolor2.h"
25
#include "gsipar3x.h"
26
#include "gstrans.h"
27
#include "gxiparam.h"		/* for image enumerator */
28
#include "gxcspace.h"
29
#include "idict.h"
30
#include "idparam.h"
31
#include "ifunc.h"
32
#include "igstate.h"
33
#include "iimage.h"
34
#include "iname.h"
35
#include "store.h"
36
#include "gsdfilt.h"
37
#include "gdevp14.h"
38
 
39
/* ------ Utilities ------ */
40
 
41
private int
42
set_float_value(i_ctx_t *i_ctx_p, int (*set_value)(gs_state *, floatp))
43
{
44
    os_ptr op = osp;
45
    double value;
46
    int code;
47
 
48
    if (real_param(op, &value) < 0)
49
	return_op_typecheck(op);
50
    if ((code = set_value(igs, value)) < 0)
51
	return code;
52
    pop(1);
53
    return 0;
54
}
55
 
56
private int
57
current_float_value(i_ctx_t *i_ctx_p,
58
		    float (*current_value)(const gs_state *))
59
{
60
    os_ptr op = osp;
61
 
62
    push(1);
63
    make_real(op, current_value(igs));
64
    return 0;
65
}
66
 
67
private int
68
enum_param(const gs_memory_t *mem, const ref *pnref, 
69
	   const char *const names[])
70
{
71
    const char *const *p;
72
    ref nsref;
73
 
74
    name_string_ref(mem, pnref, &nsref);
75
    for (p = names; *p; ++p)
76
	if (r_size(&nsref) == strlen(*p) &&
77
	    !memcmp(*p, nsref.value.const_bytes, r_size(&nsref))
78
	    )
79
	    return p - names;
80
    return_error(e_rangecheck);
81
}
82
 
83
/* ------ Graphics state operators ------ */
84
 
85
private const char *const blend_mode_names[] = {
86
    GS_BLEND_MODE_NAMES, 0
87
};
88
 
89
/* <modename> .setblendmode - */
90
private int
91
zsetblendmode(i_ctx_t *i_ctx_p)
92
{
93
    os_ptr op = osp;
94
    int code;
95
 
96
    check_type(*op, t_name);
97
    if ((code = enum_param(imemory, op, blend_mode_names)) < 0 ||
98
	(code = gs_setblendmode(igs, code)) < 0
99
	)
100
	return code;
101
    pop(1);
102
    return 0;
103
}
104
 
105
/* - .currentblendmode <modename> */
106
private int
107
zcurrentblendmode(i_ctx_t *i_ctx_p)
108
{
109
    os_ptr op = osp;
110
    const char *mode_name = blend_mode_names[gs_currentblendmode(igs)];
111
    ref nref;
112
    int code = name_enter_string(imemory, mode_name, &nref);
113
 
114
    if (code < 0)
115
	return code;
116
    push(1);
117
    *op = nref;
118
    return 0;
119
}
120
 
121
/* <0..1> .setopacityalpha - */
122
private int
123
zsetopacityalpha(i_ctx_t *i_ctx_p)
124
{
125
    return set_float_value(i_ctx_p, gs_setopacityalpha);
126
}
127
 
128
/* - .currentopacityalpha <0..1> */
129
private int
130
zcurrentopacityalpha(i_ctx_t *i_ctx_p)
131
{
132
    return current_float_value(i_ctx_p, gs_currentopacityalpha);
133
}
134
 
135
/* <0..1> .setshapealpha - */
136
private int
137
zsetshapealpha(i_ctx_t *i_ctx_p)
138
{
139
    return set_float_value(i_ctx_p, gs_setshapealpha);
140
}
141
 
142
/* - .currentshapealpha <0..1> */
143
private int
144
zcurrentshapealpha(i_ctx_t *i_ctx_p)
145
{
146
    return current_float_value(i_ctx_p, gs_currentshapealpha);
147
}
148
 
149
/* <bool> .settextknockout - */
150
private int
151
zsettextknockout(i_ctx_t *i_ctx_p)
152
{
153
    os_ptr op = osp;
154
 
155
    check_type(*op, t_boolean);
156
    gs_settextknockout(igs, op->value.boolval);
157
    pop(1);
158
    return 0;
159
}
160
 
161
/* - .currenttextknockout <bool> */
162
private int
163
zcurrenttextknockout(i_ctx_t *i_ctx_p)
164
{
165
    os_ptr op = osp;
166
 
167
    push(1);
168
    make_bool(op, gs_currenttextknockout(igs));
169
    return 0;
170
}
171
 
172
/* ------ Rendering stack operators ------ */
173
 
174
private int
175
rect_param(gs_rect *prect, os_ptr op)
176
{
177
    double coords[4];
178
    int code = num_params(op, 4, coords);
179
 
180
    if (code < 0)
181
	return code;
182
    prect->p.x = coords[0], prect->p.y = coords[1];
183
    prect->q.x = coords[2], prect->q.y = coords[3];
184
    return 0;
185
}
186
 
187
private int
188
mask_op(i_ctx_t *i_ctx_p,
189
	int (*mask_proc)(gs_state *, gs_transparency_channel_selector_t))
190
{
191
    int csel;
192
    int code = int_param(osp, 1, &csel);
193
 
194
    if (code < 0)
195
	return code;
196
    code = mask_proc(igs, csel);
197
    if (code >= 0)
198
	pop(1);
199
    return code;
200
 
201
}
202
 
203
/* <paramdict> <llx> <lly> <urx> <ury> .begintransparencygroup - */
204
private int
205
zbegintransparencygroup(i_ctx_t *i_ctx_p)
206
{
207
    os_ptr op = osp;
208
    os_ptr dop = op - 4;
209
    gs_transparency_group_params_t params;
210
    gs_rect bbox;
211
    int code;
212
 
213
    check_type(*dop, t_dictionary);
214
    check_dict_read(*dop);
215
    gs_trans_group_params_init(&params);
216
    if ((code = dict_bool_param(dop, "Isolated", false, &params.Isolated)) < 0 ||
217
	(code = dict_bool_param(dop, "Knockout", false, &params.Knockout)) < 0
218
	)
219
	return code;
220
    code = rect_param(&bbox, op);
221
    if (code < 0)
222
	return code;
223
    params.ColorSpace = gs_currentcolorspace(igs);
224
    code = gs_begin_transparency_group(igs, &params, &bbox);
225
    if (code < 0)
226
	return code;
227
    pop(5);
228
    return code;
229
}
230
 
231
/* - .discardtransparencygroup - */
232
private int
233
zdiscardtransparencygroup(i_ctx_t *i_ctx_p)
234
{
235
    if (gs_current_transparency_type(igs) != TRANSPARENCY_STATE_Group)
236
	return_error(e_rangecheck);
237
    return gs_discard_transparency_layer(igs);
238
}
239
 
240
/* - .endtransparencygroup - */
241
private int
242
zendtransparencygroup(i_ctx_t *i_ctx_p)
243
{
244
    return gs_end_transparency_group(igs);
245
}
246
 
247
/* <paramdict> <llx> <lly> <urx> <ury> .begintransparencymaskgroup - */
248
private int tf_using_function(floatp, float *, void *);
249
private int
250
zbegintransparencymaskgroup(i_ctx_t *i_ctx_p)
251
{
252
    os_ptr op = osp;
253
    os_ptr dop = op - 4;
254
    gs_transparency_mask_params_t params;
255
    ref *pparam;
256
    gs_rect bbox;
257
    int code;
258
    static const char *const subtype_names[] = {
259
	GS_TRANSPARENCY_MASK_SUBTYPE_NAMES, 0
260
    };
261
 
262
    check_type(*dop, t_dictionary);
263
    check_dict_read(*dop);
264
    if (dict_find_string(dop, "Subtype", &pparam) <= 0)
265
	return_error(e_rangecheck);
266
    if ((code = enum_param(imemory, pparam, subtype_names)) < 0)
267
	return code;
268
    gs_trans_mask_params_init(&params, code);
269
    if ((code = dict_floats_param(imemory, dop, "Background", 
270
		    cs_num_components(gs_currentcolorspace(i_ctx_p->pgs)),
271
				  params.Background, NULL)) < 0
272
	)
273
	return code;
274
    else if (code > 0)
275
	params.Background_components = code;
276
    if ((code = dict_floats_param(imemory, dop, "GrayBackground", 
277
		    1, params.Background, NULL)) < 0
278
	)
279
	return code;
280
    if (dict_find_string(dop, "TransferFunction", &pparam) >0) {
281
	gs_function_t *pfn = ref_function(pparam);
282
 
283
	if (pfn == 0 || pfn->params.m != 1 || pfn->params.n != 1)
284
	    return_error(e_rangecheck);
285
	params.TransferFunction = tf_using_function;
286
	params.TransferFunction_data = pfn;
287
    }
288
    code = rect_param(&bbox, op);
289
    if (code < 0)
290
	return code;
291
    code = gs_begin_transparency_mask(igs, &params, &bbox, false);
292
    if (code < 0)
293
	return code;
294
    pop(5);
295
    return code;
296
}
297
 
298
/* - .begintransparencymaskimage - */
299
private int
300
zbegintransparencymaskimage(i_ctx_t *i_ctx_p)
301
{
302
    gs_transparency_mask_params_t params;
303
    gs_rect bbox = { { 0, 0} , { 1, 1} };
304
    int code;
305
 
306
    gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
307
    code = gs_begin_transparency_mask(igs, &params, &bbox, true);
308
    if (code < 0)
309
	return code;
310
    return code;
311
}
312
 
313
/* Implement the TransferFunction using a Function. */
314
private int
315
tf_using_function(floatp in_val, float *out, void *proc_data)
316
{
317
    float in = in_val;
318
    gs_function_t *const pfn = proc_data;
319
 
320
    return gs_function_evaluate(pfn, &in, out);
321
}
322
 
323
/* - .discardtransparencymask - */
324
private int
325
zdiscardtransparencymask(i_ctx_t *i_ctx_p)
326
{
327
    if (gs_current_transparency_type(igs) != TRANSPARENCY_STATE_Mask)
328
	return_error(e_rangecheck);
329
    return gs_discard_transparency_layer(igs);
330
}
331
 
332
/* <mask#> .endtransparencymask - */
333
private int
334
zendtransparencymask(i_ctx_t *i_ctx_p)
335
{
336
    return mask_op(i_ctx_p, gs_end_transparency_mask);
337
}
338
 
339
/* <mask#> .inittransparencymask - */
340
private int
341
zinittransparencymask(i_ctx_t *i_ctx_p)
342
{
343
    return mask_op(i_ctx_p, gs_init_transparency_mask);
344
}
345
 
346
/* ------ Soft-mask images ------ */
347
 
348
/* <dict> .image3x - */
349
private int mask_dict_param(const gs_memory_t *mem, os_ptr, 
350
			    image_params *, const char *, int,
351
			    gs_image3x_mask_t *);
352
private int
353
zimage3x(i_ctx_t *i_ctx_p)
354
{
355
    os_ptr op = osp;
356
    gs_image3x_t image;
357
    ref *pDataDict;
358
    image_params ip_data;
359
    int num_components =
360
	gs_color_space_num_components(gs_currentcolorspace(igs));
361
    int ignored;
362
    int code;
363
 
364
    check_type(*op, t_dictionary);
365
    check_dict_read(*op);
366
    gs_image3x_t_init(&image, NULL);
367
    if (dict_find_string(op, "DataDict", &pDataDict) <= 0)
368
	return_error(e_rangecheck);
369
    if ((code = pixel_image_params(i_ctx_p, pDataDict,
370
				   (gs_pixel_image_t *)&image, &ip_data,
371
				   12, false)) < 0 ||
372
	(code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0
373
	)
374
	return code;
375
    /*
376
     * We have to process the masks in the reverse order, because they
377
     * insert their DataSource before the one(s) for the DataDict.
378
     */
379
    if ((code = mask_dict_param(imemory, op, &ip_data, 
380
				"ShapeMaskDict", num_components,
381
				&image.Shape)) < 0 ||
382
	(code = mask_dict_param(imemory, op, &ip_data, 
383
				"OpacityMaskDict", num_components,
384
				&image.Opacity)) < 0
385
	)
386
	return code;
387
    return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image,
388
			&ip_data.DataSource[0],
389
			image.CombineWithColor, 1);
390
}    
391
 
392
/* Get one soft-mask dictionary parameter. */
393
private int
394
mask_dict_param(const gs_memory_t *mem, os_ptr op, 
395
image_params *pip_data, const char *dict_name,
396
		int num_components, gs_image3x_mask_t *pixm)
397
{
398
    ref *pMaskDict;
399
    image_params ip_mask;
400
    int ignored;
401
    int code, mcode;
402
 
403
    if (dict_find_string(op, dict_name, &pMaskDict) <= 0)
404
	return 1;
405
    if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict,
406
					  &ip_mask, false, 1, 12, false)) < 0 ||
407
	(code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ||
408
	(code = dict_int_param(pMaskDict, "InterleaveType", 1, 3, -1,
409
			       &pixm->InterleaveType)) < 0 ||
410
	(code = dict_floats_param(mem, op, "Matte", num_components,
411
				  pixm->Matte, NULL)) < 0
412
	)
413
	return code;
414
    pixm->has_Matte = code > 0;
415
    /*
416
     * The MaskDict must have a DataSource iff InterleaveType == 3.
417
     */
418
    if ((pip_data->MultipleDataSources && pixm->InterleaveType != 3) ||
419
	ip_mask.MultipleDataSources ||
420
	mcode != (pixm->InterleaveType != 3)
421
	)
422
	return_error(e_rangecheck);
423
    if (pixm->InterleaveType == 3) {
424
	/* Insert the mask DataSource before the data DataSources. */
425
	memmove(&pip_data->DataSource[1], &pip_data->DataSource[0],
426
		(countof(pip_data->DataSource) - 1) *
427
		sizeof(pip_data->DataSource[0]));
428
	pip_data->DataSource[0] = ip_mask.DataSource[0];
429
    }
430
    return 0;
431
}
432
 
433
/* depth .pushpdf14devicefilter - */
434
/* this is a filter operator, but we include it here to maintain
435
   modularity of the pdf14 transparency support */
436
private int
437
zpushpdf14devicefilter(i_ctx_t *i_ctx_p)
438
{
439
    int code;
440
    os_ptr op = osp;
441
 
442
    check_type(*op, t_integer);
443
    code = gs_push_pdf14trans_device(igs); 
444
    if (code < 0)
445
        return code;
446
    pop(1);
447
    return 0;
448
}
449
 
450
/* this is a filter operator, but we include it here to maintain
451
   modularity of the pdf14 transparency support */
452
private int
453
zpoppdf14devicefilter(i_ctx_t *i_ctx_p)
454
{
455
    return gs_pop_pdf14trans_device(igs); 
456
}
457
 
458
/* ------ Initialization procedure ------ */
459
 
460
/* We need to split the table because of the 16-element limit. */
461
const op_def ztrans1_op_defs[] = {
462
    {"1.setblendmode", zsetblendmode},
463
    {"0.currentblendmode", zcurrentblendmode},
464
    {"1.setopacityalpha", zsetopacityalpha},
465
    {"0.currentopacityalpha", zcurrentopacityalpha},
466
    {"1.setshapealpha", zsetshapealpha},
467
    {"0.currentshapealpha", zcurrentshapealpha},
468
    {"1.settextknockout", zsettextknockout},
469
    {"0.currenttextknockout", zcurrenttextknockout},
470
    op_def_end(0)
471
};
472
const op_def ztrans2_op_defs[] = {
473
    {"5.begintransparencygroup", zbegintransparencygroup},
474
    {"0.discardtransparencygroup", zdiscardtransparencygroup},
475
    {"0.endtransparencygroup", zendtransparencygroup},
476
    {"5.begintransparencymaskgroup", zbegintransparencymaskgroup},
477
    {"5.begintransparencymaskimage", zbegintransparencymaskimage},
478
    {"0.discardtransparencymask", zdiscardtransparencymask},
479
    {"1.endtransparencymask", zendtransparencymask},
480
    {"1.inittransparencymask", zinittransparencymask},
481
    {"1.image3x", zimage3x},
482
    {"1.pushpdf14devicefilter", zpushpdf14devicefilter},
483
    {"0.poppdf14devicefilter", zpoppdf14devicefilter},
484
    op_def_end(0)
485
};