xref: /plan9-contrib/sys/src/cmd/gs/src/gdevpdft.c (revision 8deabd962e84f51c67a12f970084955d97d8a8f2)
17dd7cddfSDavid du Colombier /* Copyright (C) 1996, 2000 Aladdin Enterprises.  All rights reserved.
27dd7cddfSDavid du Colombier 
3*593dc095SDavid du Colombier   This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier   implied.
57dd7cddfSDavid du Colombier 
6*593dc095SDavid du Colombier   This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier   modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier   of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier 
10*593dc095SDavid du Colombier   For more information about licensing, please refer to
11*593dc095SDavid du Colombier   http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier   commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier 
17*593dc095SDavid du Colombier /* $Id: gdevpdft.c,v 1.52 2005/09/06 22:21:14 leonardo Exp $ */
18*593dc095SDavid du Colombier /* transparency processing for PDF-writing driver */
197dd7cddfSDavid du Colombier #include "gx.h"
20*593dc095SDavid du Colombier #include "string_.h"
217dd7cddfSDavid du Colombier #include "gserrors.h"
22*593dc095SDavid du Colombier #include "gstrans.h"
23*593dc095SDavid du Colombier #include "gscolor2.h"
24*593dc095SDavid du Colombier #include "gzstate.h"
257dd7cddfSDavid du Colombier #include "gdevpdfx.h"
263ff48bf5SDavid du Colombier #include "gdevpdfg.h"
27*593dc095SDavid du Colombier #include "gdevpdfo.h"
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier private int
pdf_make_soft_mask_dict(gx_device_pdf * pdev,const gs_pdf14trans_params_t * pparams)30*593dc095SDavid du Colombier pdf_make_soft_mask_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams)
317dd7cddfSDavid du Colombier {
32*593dc095SDavid du Colombier     pdf_resource_t *pres_soft_mask_dict = 0;
33*593dc095SDavid du Colombier     cos_dict_t *soft_mask_dict;
347dd7cddfSDavid du Colombier     int code;
357dd7cddfSDavid du Colombier 
36*593dc095SDavid du Colombier     /* Fixme : merge redundant objects. */
37*593dc095SDavid du Colombier     code = pdf_alloc_resource(pdev, resourceSoftMaskDict, gs_no_id, &pres_soft_mask_dict, -1);
383ff48bf5SDavid du Colombier     if (code < 0)
393ff48bf5SDavid du Colombier 	return code;
40*593dc095SDavid du Colombier     cos_become(pres_soft_mask_dict->object, cos_type_dict);
41*593dc095SDavid du Colombier     pdev->pres_soft_mask_dict = pres_soft_mask_dict;
42*593dc095SDavid du Colombier     soft_mask_dict = (cos_dict_t *)pres_soft_mask_dict->object;
43*593dc095SDavid du Colombier     code = cos_dict_put_c_key_string(soft_mask_dict, "/S",
44*593dc095SDavid du Colombier 	    pparams->subtype == TRANSPARENCY_MASK_Alpha ? (byte *)"/Alpha" : (byte *)"/Luminosity",
45*593dc095SDavid du Colombier 	    pparams->subtype == TRANSPARENCY_MASK_Alpha ? 6 : 11);
467dd7cddfSDavid du Colombier     if (code < 0)
477dd7cddfSDavid du Colombier 	return code;
48*593dc095SDavid du Colombier     if (pparams->Background_components) {
49*593dc095SDavid du Colombier 	cos_array_t *Background;
503ff48bf5SDavid du Colombier 
51*593dc095SDavid du Colombier 	Background = cos_array_from_floats(pdev, pparams->Background,
52*593dc095SDavid du Colombier 		    pparams->Background_components, "pdf_write_soft_mask_dict");
53*593dc095SDavid du Colombier 	if (Background == NULL)
54*593dc095SDavid du Colombier 	    return_error(gs_error_VMerror);
55*593dc095SDavid du Colombier 	code = cos_dict_put_c_key_object(soft_mask_dict, "/BC", (cos_object_t *)Background);
56*593dc095SDavid du Colombier 	if (code < 0)
573ff48bf5SDavid du Colombier 	    return code;
583ff48bf5SDavid du Colombier     }
59*593dc095SDavid du Colombier     if (pparams->transfer_function != NULL) {
60*593dc095SDavid du Colombier 	long id;
61*593dc095SDavid du Colombier 	char buf[20];
627dd7cddfSDavid du Colombier 
63*593dc095SDavid du Colombier 	code = pdf_write_function(pdev, pparams->transfer_function, &id);
64*593dc095SDavid du Colombier 	if (code < 0)
65*593dc095SDavid du Colombier 	    return code;
66*593dc095SDavid du Colombier 	sprintf(buf, " %ld 0 R", id);
67*593dc095SDavid du Colombier 	code = cos_dict_put_c_key_string(soft_mask_dict, "/TR", (const byte *)buf, strlen(buf));
68*593dc095SDavid du Colombier 	if (code < 0)
697dd7cddfSDavid du Colombier 	    return code;
707dd7cddfSDavid du Colombier     }
717dd7cddfSDavid du Colombier     return 0;
72*593dc095SDavid du Colombier 
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier 
757dd7cddfSDavid du Colombier private int
pdf_make_group_dict(gx_device_pdf * pdev,const gs_pdf14trans_params_t * pparams,const gs_imager_state * pis,cos_dict_t ** pdict)76*593dc095SDavid du Colombier pdf_make_group_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams,
77*593dc095SDavid du Colombier 			    const gs_imager_state * pis, cos_dict_t **pdict)
787dd7cddfSDavid du Colombier {
79*593dc095SDavid du Colombier     pdf_resource_t *pres_group;
80*593dc095SDavid du Colombier     cos_dict_t *group_dict;
81*593dc095SDavid du Colombier     int code;
82*593dc095SDavid du Colombier     const gs_state *gstate = gx_hld_get_gstate_ptr(pis);
83*593dc095SDavid du Colombier     cos_value_t cs_value;
847dd7cddfSDavid du Colombier 
85*593dc095SDavid du Colombier     code = pdf_alloc_resource(pdev, resourceGroup, gs_no_id, &pres_group, -1);
86*593dc095SDavid du Colombier     if (code < 0)
87*593dc095SDavid du Colombier 	return code;
88*593dc095SDavid du Colombier     cos_become(pres_group->object, cos_type_dict);
89*593dc095SDavid du Colombier     group_dict = (cos_dict_t *)pres_group->object;
90*593dc095SDavid du Colombier     code = cos_dict_put_c_key_string(group_dict, "/Type", (const byte *)"/Group", 6);
91*593dc095SDavid du Colombier     if (code < 0)
92*593dc095SDavid du Colombier 	return code;
93*593dc095SDavid du Colombier     code = cos_dict_put_c_key_string(group_dict, "/S", (const byte *)"/Transparency", 13);
94*593dc095SDavid du Colombier     if (code < 0)
95*593dc095SDavid du Colombier 	return code;
96*593dc095SDavid du Colombier     if (pparams->Isolated) {
97*593dc095SDavid du Colombier 	code = cos_dict_put_c_key_bool(group_dict, "/I", true);
98*593dc095SDavid du Colombier 	if (code < 0)
99*593dc095SDavid du Colombier 	    return code;
100*593dc095SDavid du Colombier     }
101*593dc095SDavid du Colombier     if (pparams->Knockout) {
102*593dc095SDavid du Colombier 	code = cos_dict_put_c_key_bool(group_dict, "/K", true);
103*593dc095SDavid du Colombier 	if (code < 0)
104*593dc095SDavid du Colombier 	    return code;
105*593dc095SDavid du Colombier     }
106*593dc095SDavid du Colombier     if (gstate != NULL) {
107*593dc095SDavid du Colombier 	const gs_color_space *cs = gstate->color_space;
108*593dc095SDavid du Colombier 
109*593dc095SDavid du Colombier 	code = pdf_color_space(pdev, &cs_value, NULL, cs,
110*593dc095SDavid du Colombier 		&pdf_color_space_names, false);
111*593dc095SDavid du Colombier 	if (code < 0)
112*593dc095SDavid du Colombier 	    return code;
113*593dc095SDavid du Colombier 	code = cos_dict_put_c_key(group_dict, "/CS", &cs_value);
114*593dc095SDavid du Colombier 	if (code < 0)
115*593dc095SDavid du Colombier 	    return code;
116*593dc095SDavid du Colombier     }
117*593dc095SDavid du Colombier     group_dict = NULL; /* The next line invalidates it. */
118*593dc095SDavid du Colombier     code = pdf_substitute_resource(pdev, &pres_group, resourceGroup, NULL, false);
119*593dc095SDavid du Colombier     if (code < 0)
120*593dc095SDavid du Colombier 	return code;
121*593dc095SDavid du Colombier     *pdict = (cos_dict_t *)pres_group->object;
1227dd7cddfSDavid du Colombier     return 0;
1237dd7cddfSDavid du Colombier }
124*593dc095SDavid du Colombier 
125*593dc095SDavid du Colombier private int
pdf_make_form_dict(gx_device_pdf * pdev,const gs_pdf14trans_params_t * pparams,const gs_imager_state * pis,const cos_dict_t * group_dict,cos_dict_t * form_dict)126*593dc095SDavid du Colombier pdf_make_form_dict(gx_device_pdf * pdev, const gs_pdf14trans_params_t * pparams,
127*593dc095SDavid du Colombier 			    const gs_imager_state * pis,
128*593dc095SDavid du Colombier 			    const cos_dict_t *group_dict, cos_dict_t *form_dict)
1297dd7cddfSDavid du Colombier {
130*593dc095SDavid du Colombier     cos_array_t *bbox_array;
131*593dc095SDavid du Colombier     float bbox[4];
132*593dc095SDavid du Colombier     gs_rect bbox_rect;
1337dd7cddfSDavid du Colombier     int code;
1347dd7cddfSDavid du Colombier 
1357dd7cddfSDavid du Colombier 
136*593dc095SDavid du Colombier     code = gs_bbox_transform(&pparams->bbox, &ctm_only(pis), &bbox_rect);
1377dd7cddfSDavid du Colombier     if (code < 0)
1387dd7cddfSDavid du Colombier 	return code;
139*593dc095SDavid du Colombier     bbox[0] = bbox_rect.p.x;
140*593dc095SDavid du Colombier     bbox[1] = bbox_rect.p.y;
141*593dc095SDavid du Colombier     bbox[2] = bbox_rect.q.x;
142*593dc095SDavid du Colombier     bbox[3] = bbox_rect.q.y;
143*593dc095SDavid du Colombier     code = cos_dict_put_c_key_string(form_dict, "/Type", (const byte *)"/XObject", 8);
144*593dc095SDavid du Colombier     if (code < 0)
145*593dc095SDavid du Colombier 	return code;
146*593dc095SDavid du Colombier     code = cos_dict_put_c_key_string(form_dict, "/Subtype", (const byte *)"/Form", 5);
147*593dc095SDavid du Colombier     if (code < 0)
148*593dc095SDavid du Colombier 	return code;
149*593dc095SDavid du Colombier     code = cos_dict_put_c_key_int(form_dict, "/FormType", 1);
150*593dc095SDavid du Colombier     if (code < 0)
151*593dc095SDavid du Colombier 	return code;
152*593dc095SDavid du Colombier     code = cos_dict_put_c_key_string(form_dict, "/Matrix", (const byte *)"[1 0 0 1 0 0]", 13);
153*593dc095SDavid du Colombier     if (code < 0)
154*593dc095SDavid du Colombier 	return code;
155*593dc095SDavid du Colombier     bbox_array = cos_array_from_floats(pdev, bbox, 4, "pdf_begin_transparency_group");
156*593dc095SDavid du Colombier     if (bbox_array == NULL)
157*593dc095SDavid du Colombier 	return_error(gs_error_VMerror);
158*593dc095SDavid du Colombier     code = cos_dict_put_c_key_object(form_dict, "/BBox", (cos_object_t *)bbox_array);
159*593dc095SDavid du Colombier     if (code < 0)
160*593dc095SDavid du Colombier 	return code;
161*593dc095SDavid du Colombier     return cos_dict_put_c_key_object(form_dict, "/Group", (cos_object_t *)group_dict);
1623ff48bf5SDavid du Colombier }
1633ff48bf5SDavid du Colombier 
164*593dc095SDavid du Colombier private int
pdf_begin_transparency_group(gs_imager_state * pis,gx_device_pdf * pdev,const gs_pdf14trans_params_t * pparams)165*593dc095SDavid du Colombier pdf_begin_transparency_group(gs_imager_state * pis, gx_device_pdf * pdev,
166*593dc095SDavid du Colombier 				const gs_pdf14trans_params_t * pparams)
167*593dc095SDavid du Colombier {
168*593dc095SDavid du Colombier     cos_dict_t *group_dict;
169*593dc095SDavid du Colombier     bool in_page = is_in_page(pdev);
170*593dc095SDavid du Colombier     const gs_state *gstate = gx_hld_get_gstate_ptr(pis);
171*593dc095SDavid du Colombier     int code;
172*593dc095SDavid du Colombier 
173*593dc095SDavid du Colombier     if (gstate == NULL)
174*593dc095SDavid du Colombier 	return_error(gs_error_unregistered); /* Must not happen. */
175*593dc095SDavid du Colombier     code = pdf_make_group_dict(pdev, pparams, pis, &group_dict);
176*593dc095SDavid du Colombier     if (code < 0)
177*593dc095SDavid du Colombier 	return code;
178*593dc095SDavid du Colombier     code = pdf_open_page(pdev, PDF_IN_STREAM);
179*593dc095SDavid du Colombier     if (code < 0)
180*593dc095SDavid du Colombier 	return code;
181*593dc095SDavid du Colombier     if (pdf_must_put_clip_path(pdev, gstate->clip_path)) {
182*593dc095SDavid du Colombier 	code = pdf_put_clip_path(pdev, gstate->clip_path);
183*593dc095SDavid du Colombier 	if (code < 0)
184*593dc095SDavid du Colombier 	    return code;
1853ff48bf5SDavid du Colombier     }
186*593dc095SDavid du Colombier     if (!in_page)
187*593dc095SDavid du Colombier 	pdev->pages[pdev->next_page].group_id = group_dict->id;
188*593dc095SDavid du Colombier     else {
189*593dc095SDavid du Colombier 	pdf_resource_t *pres, *pres_gstate = NULL;
190*593dc095SDavid du Colombier 
191*593dc095SDavid du Colombier 	code = pdf_prepare_drawing(pdev, pis, &pres_gstate);
192*593dc095SDavid du Colombier 	if (code < 0)
193*593dc095SDavid du Colombier 	    return code;
194*593dc095SDavid du Colombier 	code = pdf_end_gstate(pdev, pres_gstate);
195*593dc095SDavid du Colombier 	if (code < 0)
196*593dc095SDavid du Colombier 	    return code;
197*593dc095SDavid du Colombier 	code = pdf_enter_substream(pdev, resourceXObject,
198*593dc095SDavid du Colombier 		gs_no_id, &pres, false, pdev->params.CompressPages);
199*593dc095SDavid du Colombier 	if (code < 0)
200*593dc095SDavid du Colombier 	    return code;
201*593dc095SDavid du Colombier 	return pdf_make_form_dict(pdev, pparams, pis, group_dict, (cos_dict_t *)pres->object);
202*593dc095SDavid du Colombier     }
203*593dc095SDavid du Colombier     return 0;
204*593dc095SDavid du Colombier }
205*593dc095SDavid du Colombier 
206*593dc095SDavid du Colombier private int
pdf_end_transparency_group(gs_imager_state * pis,gx_device_pdf * pdev)207*593dc095SDavid du Colombier pdf_end_transparency_group(gs_imager_state * pis, gx_device_pdf * pdev)
208*593dc095SDavid du Colombier {
209*593dc095SDavid du Colombier     int bottom = (pdev->ResourcesBeforeUsage ? 1 : 0);
210*593dc095SDavid du Colombier 
211*593dc095SDavid du Colombier     if (pdev->sbstack_depth == bottom) {
212*593dc095SDavid du Colombier 	/* We're closing the page group. */
213*593dc095SDavid du Colombier 	if (pdev->pages[pdev->next_page].group_id == 0)
214*593dc095SDavid du Colombier 	    return_error(gs_error_unregistered); /* Must not happen. */
215*593dc095SDavid du Colombier 	return 0;
2163ff48bf5SDavid du Colombier     } else {
217*593dc095SDavid du Colombier 	pdf_resource_t *pres = pdev->accumulating_substream_resource;
218*593dc095SDavid du Colombier 	int code;
219*593dc095SDavid du Colombier 	uint ignore;
220*593dc095SDavid du Colombier 
221*593dc095SDavid du Colombier 	code = pdf_exit_substream(pdev);
2227dd7cddfSDavid du Colombier 	if (code < 0)
2237dd7cddfSDavid du Colombier 	    return code;
224*593dc095SDavid du Colombier 	code = pdf_substitute_resource(pdev, &pres, resourceXObject, NULL, false);
225*593dc095SDavid du Colombier 	if (code < 0)
226*593dc095SDavid du Colombier 	    return code;
227*593dc095SDavid du Colombier 	sputc(pdev->strm,'/');
228*593dc095SDavid du Colombier 	sputs(pdev->strm, (const byte *)pres->rname, strlen(pres->rname), &ignore);
229*593dc095SDavid du Colombier 	sputs(pdev->strm, (const byte *)" Do\n", 4, &ignore);
2307dd7cddfSDavid du Colombier 	return 0;
2317dd7cddfSDavid du Colombier     }
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier 
2347dd7cddfSDavid du Colombier private int
pdf_begin_transparency_mask(gs_imager_state * pis,gx_device_pdf * pdev,const gs_pdf14trans_params_t * pparams)235*593dc095SDavid du Colombier pdf_begin_transparency_mask(gs_imager_state * pis, gx_device_pdf * pdev,
236*593dc095SDavid du Colombier 				const gs_pdf14trans_params_t * pparams)
2377dd7cddfSDavid du Colombier {
238*593dc095SDavid du Colombier     if (pparams->mask_is_image) {
239*593dc095SDavid du Colombier 	/* HACK :
240*593dc095SDavid du Colombier 	    The control comes here when
241*593dc095SDavid du Colombier 	    the PDF interpreter will make the PS interpreter
242*593dc095SDavid du Colombier 	    to interprete the mask for filling the transparency buffer
243*593dc095SDavid du Colombier     	    with an SMask image.
244*593dc095SDavid du Colombier 	    Since we handle Type 3 images as a high level objects,
245*593dc095SDavid du Colombier 	    we don't install the transparency buffer here
246*593dc095SDavid du Colombier 	    and need to skip the image enumeration for the SMask.
247*593dc095SDavid du Colombier 	    However we have no right method for skipping
248*593dc095SDavid du Colombier 	    an image enumeration due to possible side effect
249*593dc095SDavid du Colombier 	    of the image data proc in Postscript language.
250*593dc095SDavid du Colombier 	    Therefore we do enumerate the image mask and accumulate
251*593dc095SDavid du Colombier 	    it as a PDF stream, but don't create a reference to it.
252*593dc095SDavid du Colombier 	    Later it will be enumerated once again as a part of SMask-ed image,
253*593dc095SDavid du Colombier 	    and the pdfwrite image handler will recognize duplicated images
254*593dc095SDavid du Colombier 	    and won't create the second stream for same image.
2557dd7cddfSDavid du Colombier 
256*593dc095SDavid du Colombier 	    We could make a special workaround for
257*593dc095SDavid du Colombier 	    skipping mask images either in the graphics library or
258*593dc095SDavid du Colombier 	    in the PS code of the PDF interpreter,
259*593dc095SDavid du Colombier 	    but we don't want to complicate things now.
260*593dc095SDavid du Colombier 	    The performance leak for the second enumeration
261*593dc095SDavid du Colombier 	    shouldn't be harmful.
2627dd7cddfSDavid du Colombier 
263*593dc095SDavid du Colombier 	    So now just set a flag for pdf_end_and_do_image.
264*593dc095SDavid du Colombier 	*/
265*593dc095SDavid du Colombier 	pdev->image_mask_skip = true;
266*593dc095SDavid du Colombier 	return 0;
267*593dc095SDavid du Colombier     } else {
2687dd7cddfSDavid du Colombier 	int code;
2697dd7cddfSDavid du Colombier 
270*593dc095SDavid du Colombier 	code = pdf_make_soft_mask_dict(pdev, pparams);
2717dd7cddfSDavid du Colombier 	if (code < 0)
2727dd7cddfSDavid du Colombier 	    return code;
273*593dc095SDavid du Colombier 	code = pdf_open_page(pdev, PDF_IN_STREAM);
274*593dc095SDavid du Colombier 	if (code < 0)
275*593dc095SDavid du Colombier 	    return code;
276*593dc095SDavid du Colombier 	return pdf_begin_transparency_group(pis, pdev, pparams);
277*593dc095SDavid du Colombier     }
278*593dc095SDavid du Colombier }
2797dd7cddfSDavid du Colombier 
280*593dc095SDavid du Colombier private int
pdf_end_transparency_mask(gs_imager_state * pis,gx_device_pdf * pdev,const gs_pdf14trans_params_t * pparams)281*593dc095SDavid du Colombier pdf_end_transparency_mask(gs_imager_state * pis, gx_device_pdf * pdev,
282*593dc095SDavid du Colombier 				const gs_pdf14trans_params_t * pparams)
283*593dc095SDavid du Colombier {
284*593dc095SDavid du Colombier     if (pdev->image_mask_skip)
285*593dc095SDavid du Colombier 	pdev->image_mask_skip = false;
286*593dc095SDavid du Colombier     else {
287*593dc095SDavid du Colombier 	pdf_resource_t *pres = pdev->accumulating_substream_resource;
288*593dc095SDavid du Colombier 	int code;
289*593dc095SDavid du Colombier 	char buf[20];
290*593dc095SDavid du Colombier 
291*593dc095SDavid du Colombier 	code = pdf_exit_substream(pdev);
292*593dc095SDavid du Colombier 	if (code < 0)
293*593dc095SDavid du Colombier 	    return code;
294*593dc095SDavid du Colombier 	code = pdf_substitute_resource(pdev, &pres, resourceXObject, NULL, false);
295*593dc095SDavid du Colombier 	if (code < 0)
296*593dc095SDavid du Colombier 	    return 0;
297*593dc095SDavid du Colombier 	sprintf(buf, "%ld 0 R", pdf_resource_id(pres));
298*593dc095SDavid du Colombier 	code = cos_dict_put_c_key_string((cos_dict_t *)pdev->pres_soft_mask_dict->object,
299*593dc095SDavid du Colombier 		"/G", (const byte *)buf, strlen(buf));
300*593dc095SDavid du Colombier 	if (code < 0)
301*593dc095SDavid du Colombier 	    return code;
302*593dc095SDavid du Colombier 	code = pdf_substitute_resource(pdev, &pdev->pres_soft_mask_dict,
303*593dc095SDavid du Colombier 					resourceSoftMaskDict, NULL, false);
304*593dc095SDavid du Colombier 	if (code < 0)
305*593dc095SDavid du Colombier 	    return code;
306*593dc095SDavid du Colombier 	pis->soft_mask_id = pdev->pres_soft_mask_dict->object->id;
307*593dc095SDavid du Colombier 	pdev->pres_soft_mask_dict = NULL;
3087dd7cddfSDavid du Colombier     }
3097dd7cddfSDavid du Colombier     return 0;
3107dd7cddfSDavid du Colombier }
3117dd7cddfSDavid du Colombier 
312*593dc095SDavid du Colombier private int
pdf_set_blend_params(gs_imager_state * pis,gx_device_pdf * dev,const gs_pdf14trans_params_t * pparams)313*593dc095SDavid du Colombier pdf_set_blend_params(gs_imager_state * pis, gx_device_pdf * dev,
314*593dc095SDavid du Colombier 				const gs_pdf14trans_params_t * pparams)
3157dd7cddfSDavid du Colombier {
3167dd7cddfSDavid du Colombier     return 0;
3177dd7cddfSDavid du Colombier }
3187dd7cddfSDavid du Colombier 
3197dd7cddfSDavid du Colombier int
gdev_pdf_create_compositor(gx_device * dev,gx_device ** pcdev,const gs_composite_t * pct,gs_imager_state * pis,gs_memory_t * memory)320*593dc095SDavid du Colombier gdev_pdf_create_compositor(gx_device *dev,
321*593dc095SDavid du Colombier     gx_device **pcdev, const gs_composite_t *pct,
322*593dc095SDavid du Colombier     gs_imager_state *pis, gs_memory_t *memory)
3237dd7cddfSDavid du Colombier {
324*593dc095SDavid du Colombier     gx_device_pdf *pdev = (gx_device_pdf *)dev;
3257dd7cddfSDavid du Colombier 
326*593dc095SDavid du Colombier     if (pdev->HaveTransparency && pdev->CompatibilityLevel >= 1.4 &&
327*593dc095SDavid du Colombier 	    pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
328*593dc095SDavid du Colombier 	gs_pdf14trans_t *pcte = (gs_pdf14trans_t *)pct;
329*593dc095SDavid du Colombier 	gs_pdf14trans_params_t *params = &pcte->params;
330*593dc095SDavid du Colombier 
331*593dc095SDavid du Colombier 	*pcdev = dev;
332*593dc095SDavid du Colombier 	switch(params->pdf14_op) {
333*593dc095SDavid du Colombier 	    case PDF14_PUSH_DEVICE:
334*593dc095SDavid du Colombier 		return 0;
335*593dc095SDavid du Colombier 	    case PDF14_POP_DEVICE:
336*593dc095SDavid du Colombier 		return 0;
337*593dc095SDavid du Colombier 	    case PDF14_BEGIN_TRANS_GROUP:
338*593dc095SDavid du Colombier 		return pdf_begin_transparency_group(pis, pdev, params);
339*593dc095SDavid du Colombier 	    case PDF14_END_TRANS_GROUP:
340*593dc095SDavid du Colombier 		return pdf_end_transparency_group(pis, pdev);
341*593dc095SDavid du Colombier 	    case PDF14_INIT_TRANS_MASK:
342*593dc095SDavid du Colombier 		return gx_init_transparency_mask(pis, params);
343*593dc095SDavid du Colombier 	    case PDF14_BEGIN_TRANS_MASK:
344*593dc095SDavid du Colombier 		return pdf_begin_transparency_mask(pis, pdev, params);
345*593dc095SDavid du Colombier 	    case PDF14_END_TRANS_MASK:
346*593dc095SDavid du Colombier 		return pdf_end_transparency_mask(pis, pdev, params);
347*593dc095SDavid du Colombier 	    case PDF14_SET_BLEND_PARAMS:
348*593dc095SDavid du Colombier 		return pdf_set_blend_params(pis, pdev, params);
349*593dc095SDavid du Colombier 	    default :
350*593dc095SDavid du Colombier 		return_error(gs_error_unregistered); /* Must not happen. */
3517dd7cddfSDavid du Colombier 	}
352*593dc095SDavid du Colombier     }
353*593dc095SDavid du Colombier     return psdf_create_compositor(dev, pcdev, pct, pis, memory);
354*593dc095SDavid du Colombier }
355*593dc095SDavid du Colombier 
356*593dc095SDavid du Colombier /* We're not sure why the folllowing device methods are never called.
357*593dc095SDavid du Colombier    Stub them for a while. */
358*593dc095SDavid du Colombier 
359*593dc095SDavid du Colombier int
gdev_pdf_begin_transparency_group(gx_device * dev,const gs_transparency_group_params_t * ptgp,const gs_rect * pbbox,gs_imager_state * pis,gs_transparency_state_t ** ppts,gs_memory_t * mem)360*593dc095SDavid du Colombier gdev_pdf_begin_transparency_group(gx_device *dev,
361*593dc095SDavid du Colombier     const gs_transparency_group_params_t *ptgp,
362*593dc095SDavid du Colombier     const gs_rect *pbbox,
363*593dc095SDavid du Colombier     gs_imager_state *pis,
364*593dc095SDavid du Colombier     gs_transparency_state_t **ppts,
365*593dc095SDavid du Colombier     gs_memory_t *mem)
366*593dc095SDavid du Colombier {
367*593dc095SDavid du Colombier     return 0;
368*593dc095SDavid du Colombier }
369*593dc095SDavid du Colombier 
370*593dc095SDavid du Colombier int
gdev_pdf_end_transparency_group(gx_device * dev,gs_imager_state * pis,gs_transparency_state_t ** ppts)371*593dc095SDavid du Colombier gdev_pdf_end_transparency_group(gx_device *dev,
372*593dc095SDavid du Colombier     gs_imager_state *pis,
373*593dc095SDavid du Colombier     gs_transparency_state_t **ppts)
374*593dc095SDavid du Colombier {
375*593dc095SDavid du Colombier     return 0;
376*593dc095SDavid du Colombier }
377*593dc095SDavid du Colombier 
378*593dc095SDavid du Colombier int
gdev_pdf_begin_transparency_mask(gx_device * dev,const gx_transparency_mask_params_t * ptmp,const gs_rect * pbbox,gs_imager_state * pis,gs_transparency_state_t ** ppts,gs_memory_t * mem)379*593dc095SDavid du Colombier gdev_pdf_begin_transparency_mask(gx_device *dev,
380*593dc095SDavid du Colombier     const gx_transparency_mask_params_t *ptmp,
381*593dc095SDavid du Colombier     const gs_rect *pbbox,
382*593dc095SDavid du Colombier     gs_imager_state *pis,
383*593dc095SDavid du Colombier     gs_transparency_state_t **ppts,
384*593dc095SDavid du Colombier     gs_memory_t *mem)
385*593dc095SDavid du Colombier {
386*593dc095SDavid du Colombier     return 0;
387*593dc095SDavid du Colombier }
388*593dc095SDavid du Colombier 
389*593dc095SDavid du Colombier int
gdev_pdf_end_transparency_mask(gx_device * dev,gs_transparency_mask_t ** pptm)390*593dc095SDavid du Colombier gdev_pdf_end_transparency_mask(gx_device *dev,
391*593dc095SDavid du Colombier     gs_transparency_mask_t **pptm)
392*593dc095SDavid du Colombier {
393*593dc095SDavid du Colombier     return 0;
394*593dc095SDavid du Colombier }
395*593dc095SDavid du Colombier 
396*593dc095SDavid du Colombier int
gdev_pdf_discard_transparency_layer(gx_device * dev,gs_transparency_state_t ** ppts)397*593dc095SDavid du Colombier gdev_pdf_discard_transparency_layer(gx_device *dev,
398*593dc095SDavid du Colombier     gs_transparency_state_t **ppts)
399*593dc095SDavid du Colombier {
4007dd7cddfSDavid du Colombier     return 0;
4017dd7cddfSDavid du Colombier }
402