1 /* Copyright (C) 1999, 2000 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: gdevpdfg.c,v 1.14.2.1.2.1 2003/01/17 00:49:01 giles Exp $ */
20 /* Graphics state management for pdfwrite driver */
21 #include "math_.h"
22 #include "string_.h"
23 #include "gx.h"
24 #include "gserrors.h"
25 #include "gsfunc0.h"
26 #include "gsstate.h"
27 #include "gxbitmap.h"		/* for gxhttile.h in gzht.h */
28 #include "gxdht.h"
29 #include "gxfarith.h"		/* for gs_sin/cos_degrees */
30 #include "gxfmap.h"
31 #include "gxht.h"
32 #include "gxistate.h"
33 #include "gzht.h"
34 #include "gdevpdfx.h"
35 #include "gdevpdfg.h"
36 #include "gdevpdfo.h"
37 #include "szlibx.h"
38 
39 /* ---------------- Miscellaneous ---------------- */
40 
41 /* Reset the graphics state parameters to initial values. */
42 void
pdf_reset_graphics(gx_device_pdf * pdev)43 pdf_reset_graphics(gx_device_pdf * pdev)
44 {
45     gx_color_index color = 0; /* black on DeviceGray and DeviceRGB */
46     if(pdev->color_info.num_components == 4) {
47         color = gx_map_cmyk_color((gx_device *)pdev,
48 		      frac2cv(frac_0), frac2cv(frac_0),
49 		      frac2cv(frac_0), frac2cv(frac_1));
50     }
51     color_set_pure(&pdev->fill_color, color);
52     color_set_pure(&pdev->stroke_color, color);
53     pdev->state.flatness = -1;
54     {
55 	static const gx_line_params lp_initial = {
56 	    gx_line_params_initial
57 	};
58 
59 	pdev->state.line_params = lp_initial;
60     }
61     pdev->fill_overprint = false;
62     pdev->stroke_overprint = false;
63     pdf_reset_text(pdev);
64 }
65 
66 /* Set the fill or stroke color. */
67 private int
pdf_reset_color(gx_device_pdf * pdev,const gx_drawing_color * pdc,gx_drawing_color * pdcolor,const psdf_set_color_commands_t * ppscc)68 pdf_reset_color(gx_device_pdf * pdev, const gx_drawing_color *pdc,
69 		gx_drawing_color * pdcolor,
70 		const psdf_set_color_commands_t *ppscc)
71 {
72     int code;
73 
74     /*
75      * In principle, we can set colors in either stream or text
76      * context.  However, since we currently enclose all text
77      * strings inside a gsave/grestore, this causes us to lose
78      * track of the color when we leave text context.  Therefore,
79      * we require stream context for setting colors.
80      */
81 #if 0
82     switch (pdev->context) {
83     case PDF_IN_STREAM:
84     case PDF_IN_TEXT:
85 	break;
86     case PDF_IN_NONE:
87 	code = pdf_open_page(pdev, PDF_IN_STREAM);
88 	goto open;
89     case PDF_IN_STRING:
90 	code = pdf_open_page(pdev, PDF_IN_TEXT);
91     open:if (code < 0)
92 	    return code;
93     }
94 #else
95     code = pdf_open_page(pdev, PDF_IN_STREAM);
96     if (code < 0)
97 	return code;
98 #endif
99     code = pdf_put_drawing_color(pdev, pdc, ppscc);
100     if (code >= 0)
101 	*pdcolor = *pdc;
102     return code;
103 }
104 int
pdf_set_drawing_color(gx_device_pdf * pdev,const gx_drawing_color * pdc,gx_drawing_color * pdcolor,const psdf_set_color_commands_t * ppscc)105 pdf_set_drawing_color(gx_device_pdf * pdev, const gx_drawing_color *pdc,
106 		      gx_drawing_color * pdcolor,
107 		      const psdf_set_color_commands_t *ppscc)
108 {
109     if (gx_device_color_equal(pdcolor, pdc))
110 	return 0;
111     return pdf_reset_color(pdev, pdc, pdcolor, ppscc);
112 }
113 int
pdf_set_pure_color(gx_device_pdf * pdev,gx_color_index color,gx_drawing_color * pdcolor,const psdf_set_color_commands_t * ppscc)114 pdf_set_pure_color(gx_device_pdf * pdev, gx_color_index color,
115 		   gx_drawing_color * pdcolor,
116 		   const psdf_set_color_commands_t *ppscc)
117 {
118     gx_drawing_color dcolor;
119 
120     if (gx_dc_is_pure(pdcolor) && gx_dc_pure_color(pdcolor) == color)
121 	return 0;
122     color_set_pure(&dcolor, color);
123     return pdf_reset_color(pdev, &dcolor, pdcolor, ppscc);
124 }
125 
126 /* Get the (string) name of a separation, */
127 /* returning a newly allocated string with a / prefixed. */
128 /****** BOGUS for all but standard separations ******/
129 int
pdf_separation_name(gx_device_pdf * pdev,cos_value_t * pvalue,gs_separation_name sname)130 pdf_separation_name(gx_device_pdf *pdev, cos_value_t *pvalue,
131 		    gs_separation_name sname)
132 {
133     static const char *const snames[] = {
134 	gs_ht_separation_name_strings
135     };
136     static char buf[sizeof(ulong) * 8 / 3 + 2];	/****** BOGUS ******/
137     const char *str;
138     uint len;
139     byte *chars;
140 
141     if ((ulong)sname < countof(snames)) {
142 	str = snames[(int)sname];
143     } else {			/****** TOTALLY BOGUS ******/
144 	sprintf(buf, "S%ld", (ulong)sname);
145 	str = buf;
146     }
147     len = strlen(str);
148     chars = gs_alloc_string(pdev->pdf_memory, len + 1, "pdf_separation_name");
149     if (chars == 0)
150 	return_error(gs_error_VMerror);
151     chars[0] = '/';
152     memcpy(chars + 1, str, len);
153     cos_string_value(pvalue, chars, len + 1);
154     return 0;
155 }
156 
157 /* ------ Support ------ */
158 
159 /* Print a Boolean using a format. */
160 private void
pprintb1(stream * s,const char * format,bool b)161 pprintb1(stream *s, const char *format, bool b)
162 {
163     pprints1(s, format, (b ? "true" : "false"));
164 }
165 
166 /* ---------------- Graphics state updating ---------------- */
167 
168 /* ------ Functions ------ */
169 
170 /* Define the maximum size of a Function reference. */
171 #define MAX_FN_NAME_CHARS 9	/* /Default, /Identity */
172 #define MAX_FN_CHARS max(MAX_REF_CHARS + 4, MAX_FN_NAME_CHARS)
173 
174 /*
175  * Create and write a Function for a gx_transfer_map.  We use this for
176  * transfer, BG, and UCR functions.  If check_identity is true, check for
177  * an identity map.  Return 1 if the map is the identity map, otherwise
178  * return 0.
179  */
180 private data_source_proc_access(transfer_map_access); /* check prototype */
181 private int
transfer_map_access(const gs_data_source_t * psrc,ulong start,uint length,byte * buf,const byte ** ptr)182 transfer_map_access(const gs_data_source_t *psrc, ulong start, uint length,
183 		    byte *buf, const byte **ptr)
184 {
185     const gx_transfer_map *map = (const gx_transfer_map *)psrc->data.str.data;
186     uint i;
187 
188     if (ptr)
189 	*ptr = buf;
190     for (i = 0; i < length; ++i)
191 	buf[i] = frac2byte(map->values[(uint)start + i]);
192     return 0;
193 }
194 private int
transfer_map_access_signed(const gs_data_source_t * psrc,ulong start,uint length,byte * buf,const byte ** ptr)195 transfer_map_access_signed(const gs_data_source_t *psrc,
196 			   ulong start, uint length,
197 			   byte *buf, const byte **ptr)
198 {
199     const gx_transfer_map *map = (const gx_transfer_map *)psrc->data.str.data;
200     uint i;
201 
202     *ptr = buf;
203     for (i = 0; i < length; ++i)
204 	buf[i] = (byte)
205 	    ((frac2float(map->values[(uint)start + i]) + 1) * 127.5 + 0.5);
206     return 0;
207 }
208 private int
pdf_write_transfer_map(gx_device_pdf * pdev,const gx_transfer_map * map,int range0,bool check_identity,const char * key,char * ids)209 pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
210 		       int range0, bool check_identity,
211 		       const char *key, char *ids)
212 {
213     gs_memory_t *mem = pdev->pdf_memory;
214     gs_function_Sd_params_t params;
215     static const float domain01[2] = { 0, 1 };
216     static const int size = transfer_map_size;
217     float range01[2];
218     gs_function_t *pfn;
219     long id;
220     int code;
221 
222     if (map == 0) {
223 	*ids = 0;		/* no map */
224 	return 1;
225     }
226     if (check_identity) {
227 	/* Check for an identity map. */
228 	int i;
229 
230 	if (map->proc == gs_identity_transfer)
231 	    i = transfer_map_size;
232 	else
233 	    for (i = 0; i < transfer_map_size; ++i)
234 		if (map->values[i] != bits2frac(i, log2_transfer_map_size))
235 		    break;
236 	if (i == transfer_map_size) {
237 	    strcpy(ids, key);
238 	    strcat(ids, "/Identity");
239 	    return 1;
240 	}
241     }
242     params.m = 1;
243     params.Domain = domain01;
244     params.n = 1;
245     range01[0] = range0, range01[1] = 1;
246     params.Range = range01;
247     params.Order = 1;
248     params.DataSource.access =
249 	(range0 < 0 ? transfer_map_access_signed : transfer_map_access);
250     params.DataSource.data.str.data = (const byte *)map; /* bogus */
251     /* DataSource */
252     params.BitsPerSample = 8;	/* could be 16 */
253     params.Encode = 0;
254     params.Decode = 0;
255     params.Size = &size;
256     code = gs_function_Sd_init(&pfn, &params, mem);
257     if (code < 0)
258 	return code;
259     code = pdf_write_function(pdev, pfn, &id);
260     gs_function_free(pfn, false, mem);
261     if (code < 0)
262 	return code;
263     sprintf(ids, "%s %ld 0 R", key, id);
264     return 0;
265 }
266 private int
pdf_write_transfer(gx_device_pdf * pdev,const gx_transfer_map * map,const char * key,char * ids)267 pdf_write_transfer(gx_device_pdf *pdev, const gx_transfer_map *map,
268 		   const char *key, char *ids)
269 {
270     return pdf_write_transfer_map(pdev, map, 0, true, key, ids);
271 }
272 
273 /* ------ Halftones ------ */
274 
275 /*
276  * Recognize the predefined PDF halftone functions.  Note that because the
277  * corresponding PostScript functions use single-precision floats, the
278  * functions used for testing must do the same in order to get identical
279  * results.  Currently we only do this for a few of the functions.
280  */
281 #ifdef __PROTOTYPES__
282 #define HT_FUNC(name, expr)\
283   private floatp name(floatp xd, floatp yd) {\
284     float x = (float)xd, y = (float)yd;\
285     return d2f(expr);\
286   }
287 #else
288 #define HT_FUNC(name, expr)\
289   private floatp name(x, y) floatp x, y; {\
290     float x = (float)xd, y = (float)yd;\
291     return d2f(expr);\
292   }
293 #endif
294 /*
295  * In most versions of gcc (e.g., 2.7.2.3, 2.95.4), return (float)xxx
296  * doesn't actually do the coercion.  Force this here.  Note that if we
297  * use 'inline', it doesn't work.
298  */
299 private float
d2f(floatp d)300 d2f(floatp d)
301 {
302     float f = (float)d;
303     return f;
304 }
305 private floatp
ht_Round(floatp xf,floatp yf)306 ht_Round(floatp xf, floatp yf)
307 {
308     float x = (float)xf, y = (float)yf;
309     float xabs = fabs(x), yabs = fabs(y);
310 
311     if (d2f(xabs + yabs) <= 1)
312 	return d2f(1 - d2f(d2f(x * x) + d2f(y * y)));
313     xabs -= 1, yabs -= 1;
314     return d2f(d2f(d2f(xabs * xabs) + d2f(yabs * yabs)) - 1);
315 }
316 private floatp
ht_Diamond(floatp xf,floatp yf)317 ht_Diamond(floatp xf, floatp yf)
318 {
319     float x = (float)xf, y = (float)yf;
320     float xabs = fabs(x), yabs = fabs(y);
321 
322     if (d2f(xabs + yabs) <= 0.75)
323 	return d2f(1 - d2f(d2f(x * x) + d2f(y * y)));
324     if (d2f(xabs + yabs) <= d2f(1.23))
325 	return d2f(1 - d2f(d2f(d2f(0.85) * xabs) + yabs));
326     xabs -= 1, yabs -= 1;
327     return d2f(d2f(d2f(xabs * xabs) + d2f(yabs * yabs)) - 1);
328 }
329 private floatp
ht_Ellipse(floatp xf,floatp yf)330 ht_Ellipse(floatp xf, floatp yf)
331 {
332     float x = (float)xf, y = (float)yf;
333     float xabs = fabs(x), yabs = fabs(y);
334     /*
335      * The PDF Reference, 2nd edition, incorrectly specifies the
336      * computation w = 4 * |x| + 3 * |y| - 3.  The PostScript code in the
337      * same book correctly implements w = 3 * |x| + 4 * |y| - 3.
338      */
339     float w = (float)(d2f(d2f(3 * xabs) + d2f(4 * yabs)) - 3);
340 
341     if (w < 0) {
342 	yabs /= 0.75;
343 	return d2f(1 - d2f((d2f(x * x) + d2f(yabs * yabs)) / 4));
344     }
345     if (w > 1) {
346 	xabs = 1 - xabs, yabs = d2f(1 - yabs) / 0.75;
347 	return d2f(d2f((d2f(xabs * xabs) + d2f(yabs * yabs)) / 4) - 1);
348     }
349     return d2f(0.5 - w);
350 }
351 /*
352  * Most of these are recognized properly even without d2f.  We've only
353  * added d2f where it apparently makes a difference.
354  */
355 private float
d2fsin_d(double x)356 d2fsin_d(double x) {
357     return d2f(gs_sin_degrees(d2f(x)));
358 }
359 private float
d2fcos_d(double x)360 d2fcos_d(double x) {
361     return d2f(gs_cos_degrees(d2f(x)));
362 }
363 HT_FUNC(ht_EllipseA, 1 - (x * x + 0.9 * y * y))
364 HT_FUNC(ht_InvertedEllipseA, x * x + 0.9 * y * y - 1)
365 HT_FUNC(ht_EllipseB, 1 - sqrt(x * x + 0.625 * y * y))
366 HT_FUNC(ht_EllipseC, 1 - (0.9 * x * x + y * y))
367 HT_FUNC(ht_InvertedEllipseC, 0.9 * x * x + y * y - 1)
368 HT_FUNC(ht_Line, -fabs(y))
369 HT_FUNC(ht_LineX, x)
370 HT_FUNC(ht_LineY, y)
371 HT_FUNC(ht_Square, -max(fabs(x), fabs(y)))
372 HT_FUNC(ht_Cross, -min(fabs(x), fabs(y)))
373 HT_FUNC(ht_Rhomboid, (0.9 * fabs(x) + fabs(y)) / 2)
374 HT_FUNC(ht_DoubleDot, (d2fsin_d(x * 360) + d2fsin_d(y * 360)) / 2)
375 HT_FUNC(ht_InvertedDoubleDot, -(d2fsin_d(x * 360) + d2fsin_d(y * 360)) / 2)
376 HT_FUNC(ht_SimpleDot, 1 - d2f(d2f(x * x) + d2f(y * y)))
377 HT_FUNC(ht_InvertedSimpleDot, d2f(d2f(x * x) + d2f(y * y)) - 1)
378 HT_FUNC(ht_CosineDot, (d2fcos_d(x * 180) + d2fcos_d(y * 180)) / 2)
379 HT_FUNC(ht_Double, (d2fsin_d(x * 180) + d2fsin_d(y * 360)) / 2)
380 HT_FUNC(ht_InvertedDouble, -(d2fsin_d(x * 180) + d2fsin_d(y * 360)) / 2)
381 typedef struct ht_function_s {
382     const char *fname;
383     floatp (*proc)(P2(floatp, floatp));
384 } ht_function_t;
385 private const ht_function_t ht_functions[] = {
386     {"Round", ht_Round},
387     {"Diamond", ht_Diamond},
388     {"Ellipse", ht_Ellipse},
389     {"EllipseA", ht_EllipseA},
390     {"InvertedEllipseA", ht_InvertedEllipseA},
391     {"EllipseB", ht_EllipseB},
392     {"EllipseC", ht_EllipseC},
393     {"InvertedEllipseC", ht_InvertedEllipseC},
394     {"Line", ht_Line},
395     {"LineX", ht_LineX},
396     {"LineY", ht_LineY},
397     {"Square", ht_Square},
398     {"Cross", ht_Cross},
399     {"Rhomboid", ht_Rhomboid},
400     {"DoubleDot", ht_DoubleDot},
401     {"InvertedDoubleDot", ht_InvertedDoubleDot},
402     {"SimpleDot", ht_SimpleDot},
403     {"InvertedSimpleDot", ht_InvertedSimpleDot},
404     {"CosineDot", ht_CosineDot},
405     {"Double", ht_Double},
406     {"InvertedDouble", ht_InvertedDouble}
407 };
408 
409 /* Write each kind of halftone. */
410 private int
pdf_write_spot_function(gx_device_pdf * pdev,const gx_ht_order * porder,long * pid)411 pdf_write_spot_function(gx_device_pdf *pdev, const gx_ht_order *porder,
412 			long *pid)
413 {
414     /****** DOESN'T HANDLE STRIP HALFTONES ******/
415     int w = porder->width, h = porder->height;
416     uint num_bits = porder->num_bits;
417     gs_function_Sd_params_t params;
418     static const float domain_spot[4] = { -1, 1, -1, 1 };
419     static const float range_spot[4] = { -1, 1 };
420     int size[2];
421     gs_memory_t *mem = pdev->pdf_memory;
422     /*
423      * Even though the values are logically ushort, we must always store
424      * them in big-endian order, so we access them as bytes.
425      */
426     byte *values;
427     gs_function_t *pfn;
428     uint i;
429     int code = 0;
430 
431     params.m = 2;
432     params.Domain = domain_spot;
433     params.n = 1;
434     params.Range = range_spot;
435     params.Order = 0;		/* default */
436     /*
437      * We could use 8, 16, or 32 bits per sample to save space, but for
438      * simplicity, we always use 16.
439      */
440     if (num_bits > 0x10000)
441 	return_error(gs_error_rangecheck);
442     params.BitsPerSample = 16;
443     params.Encode = 0;
444     /*
445      * The default Decode array maps the actual data values [1 .. w*h] to a
446      * sub-interval of the Range, but that's OK, since all that matters is
447      * the relative values, not the absolute values.
448      */
449     params.Decode = 0;
450     size[0] = w;
451     size[1] = h;
452     params.Size = size;
453     /* Create the (temporary) threshold array. */
454     values = gs_alloc_byte_array(mem, num_bits, 2, "pdf_write_spot_function");
455     if (values == 0)
456 	return_error(gs_error_VMerror);
457     for (i = 0; i < num_bits; ++i) {
458 	gs_int_point pt;
459 	int value;
460 
461 	if ((code = porder->procs->bit_index(porder, i, &pt)) < 0)
462 	    break;
463 	value = pt.y * w + pt.x;
464 	/* Always store the values in big-endian order. */
465 	values[i * 2] = (byte)(value >> 8);
466 	values[i * 2 + 1] = (byte)value;
467     }
468     data_source_init_bytes(&params.DataSource, (const byte *)values,
469 			   sizeof(*values) * num_bits);
470     if (code >= 0 &&
471 	(code = gs_function_Sd_init(&pfn, &params, mem)) >= 0
472 	) {
473 	code = pdf_write_function(pdev, pfn, pid);
474 	gs_function_free(pfn, false, mem);
475     }
476     gs_free_object(mem, values, "pdf_write_spot_function");
477     return code;
478 }
479 private int
pdf_write_spot_halftone(gx_device_pdf * pdev,const gs_spot_halftone * psht,const gx_ht_order * porder,long * pid)480 pdf_write_spot_halftone(gx_device_pdf *pdev, const gs_spot_halftone *psht,
481 			const gx_ht_order *porder, long *pid)
482 {
483     char trs[17 + MAX_FN_CHARS + 1];
484     int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
485 				  trs);
486     long id, spot_id;
487     stream *s;
488     int i = countof(ht_functions);
489     gs_memory_t *mem = pdev->pdf_memory;
490 
491     if (code < 0)
492 	return code;
493     /*
494      * See if we can recognize the spot function, by comparing its sampled
495      * values against those in the order.
496      */
497     {
498 	gs_screen_enum senum;
499 	gx_ht_order order;
500 	int code;
501 
502 	order = *porder;
503 	code = gs_screen_order_alloc(&order, mem);
504 	if (code < 0)
505 	    goto notrec;
506 	for (i = 0; i < countof(ht_functions); ++i) {
507 	    floatp (*spot_proc)(P2(floatp, floatp)) = ht_functions[i].proc;
508 	    gs_point pt;
509 
510 	    gs_screen_enum_init_memory(&senum, &order, NULL, &psht->screen,
511 				       mem);
512 	    while ((code = gs_screen_currentpoint(&senum, &pt)) == 0 &&
513 		   gs_screen_next(&senum, spot_proc(pt.x, pt.y)) >= 0)
514 		DO_NOTHING;
515 	    if (code < 0)
516 		continue;
517 	    /* Compare the bits and levels arrays. */
518 	    if (memcmp(order.levels, porder->levels,
519 		       order.num_levels * sizeof(*order.levels)))
520 		continue;
521 	    if (memcmp(order.bit_data, porder->bit_data,
522 		       order.num_bits * porder->procs->bit_data_elt_size))
523 		continue;
524 	    /* We have a match. */
525 	    break;
526 	}
527 	gx_ht_order_release(&order, mem, false);
528     }
529  notrec:
530     if (i == countof(ht_functions)) {
531 	/* Create and write a Function for the spot function. */
532 	pdf_write_spot_function(pdev, porder, &spot_id);
533     }
534     *pid = id = pdf_begin_separate(pdev);
535     s = pdev->strm;
536     /* Use the original, requested frequency and angle. */
537     pprintg2(s, "<</Type/Halftone/HalftoneType 1/Frequency %g/Angle %g",
538 	     psht->screen.frequency, psht->screen.angle);
539     if (i < countof(ht_functions))
540 	pprints1(s, "/SpotFunction/%s", ht_functions[i].fname);
541     else
542 	pprintld1(s, "/SpotFunction %ld 0 R", spot_id);
543     stream_puts(s, trs);
544     if (psht->accurate_screens)
545 	stream_puts(s, "/AccurateScreens true");
546     stream_puts(s, ">>\n");
547     return pdf_end_separate(pdev);
548 }
549 private int
pdf_write_screen_halftone(gx_device_pdf * pdev,const gs_screen_halftone * psht,const gx_ht_order * porder,long * pid)550 pdf_write_screen_halftone(gx_device_pdf *pdev, const gs_screen_halftone *psht,
551 			  const gx_ht_order *porder, long *pid)
552 {
553     gs_spot_halftone spot;
554 
555     spot.screen = *psht;
556     spot.accurate_screens = false;
557     spot.transfer = 0;
558     spot.transfer_closure.proc = 0;
559     return pdf_write_spot_halftone(pdev, &spot, porder, pid);
560 }
561 private int
pdf_write_colorscreen_halftone(gx_device_pdf * pdev,const gs_colorscreen_halftone * pcsht,const gx_device_halftone * pdht,long * pid)562 pdf_write_colorscreen_halftone(gx_device_pdf *pdev,
563 			       const gs_colorscreen_halftone *pcsht,
564 			       const gx_device_halftone *pdht, long *pid)
565 {
566     int i;
567     stream *s;
568     long ht_ids[4];
569 
570     for (i = 0; i < 4; ++i) {
571 	int code = pdf_write_screen_halftone(pdev, &pcsht->screens.indexed[i],
572 					     &pdht->components[i].corder,
573 					     &ht_ids[i]);
574 	if (code < 0)
575 	    return code;
576     }
577     *pid = pdf_begin_separate(pdev);
578     s = pdev->strm;
579     pprintld1(s, "<</Type/Halftone/HalftoneType 5/Default %ld 0 R\n",
580 	      ht_ids[3]);
581     pprintld2(s, "/Red %ld 0 R/Cyan %ld 0 R", ht_ids[0], ht_ids[0]);
582     pprintld2(s, "/Green %ld 0 R/Magenta %ld 0 R", ht_ids[1], ht_ids[1]);
583     pprintld2(s, "/Blue %ld 0 R/Yellow %ld 0 R", ht_ids[2], ht_ids[2]);
584     pprintld2(s, "/Gray %ld 0 R/Black %ld 0 R", ht_ids[3], ht_ids[3]);
585     return pdf_end_separate(pdev);
586 }
587 private int
pdf_write_threshold_halftone(gx_device_pdf * pdev,const gs_threshold_halftone * ptht,const gx_ht_order * porder,long * pid)588 pdf_write_threshold_halftone(gx_device_pdf *pdev,
589 			     const gs_threshold_halftone *ptht,
590 			     const gx_ht_order *porder, long *pid)
591 {
592     char trs[17 + MAX_FN_CHARS + 1];
593     int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
594 				  trs);
595     long id = pdf_begin_separate(pdev);
596     stream *s = pdev->strm;
597     pdf_data_writer_t writer;
598 
599     if (code < 0)
600 	return code;
601     *pid = id;
602     pprintd2(s, "<</Type/Halftone/HalftoneType 6/Width %d/Height %d",
603 	     ptht->width, ptht->height);
604     stream_puts(s, trs);
605     code = pdf_begin_data(pdev, &writer);
606     if (code < 0)
607 	return code;
608     stream_write(writer.binary.strm, ptht->thresholds.data, ptht->thresholds.size);
609     return pdf_end_data(&writer);
610 }
611 private int
pdf_write_threshold2_halftone(gx_device_pdf * pdev,const gs_threshold2_halftone * ptht,const gx_ht_order * porder,long * pid)612 pdf_write_threshold2_halftone(gx_device_pdf *pdev,
613 			      const gs_threshold2_halftone *ptht,
614 			      const gx_ht_order *porder, long *pid)
615 {
616     char trs[17 + MAX_FN_CHARS + 1];
617     int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
618 				  trs);
619     long id = pdf_begin_separate(pdev);
620     stream *s = pdev->strm;
621     pdf_data_writer_t writer;
622 
623     if (code < 0)
624 	return code;
625     *pid = id;
626     pprintd2(s, "<</Type/Halftone/HalftoneType 16/Width %d/Height %d",
627 	     ptht->width, ptht->height);
628     if (ptht->width2 && ptht->height2)
629 	pprintd2(s, "/Width2 %d/Height2 %d", ptht->width2, ptht->height2);
630     stream_puts(s, trs);
631     code = pdf_begin_data(pdev, &writer);
632     if (code < 0)
633 	return code;
634     s = writer.binary.strm;
635     if (ptht->bytes_per_sample == 2)
636 	stream_write(s, ptht->thresholds.data, ptht->thresholds.size);
637     else {
638 	/* Expand 1-byte to 2-byte samples. */
639 	int i;
640 
641 	for (i = 0; i < ptht->thresholds.size; ++i) {
642 	    byte b = ptht->thresholds.data[i];
643 
644 	    stream_putc(s, b);
645 	    stream_putc(s, b);
646 	}
647     }
648     return pdf_end_data(&writer);
649 }
650 private int
pdf_write_multiple_halftone(gx_device_pdf * pdev,const gs_multiple_halftone * pmht,const gx_device_halftone * pdht,long * pid)651 pdf_write_multiple_halftone(gx_device_pdf *pdev,
652 			    const gs_multiple_halftone *pmht,
653 			    const gx_device_halftone *pdht, long *pid)
654 {
655     stream *s;
656     int i, code;
657     gs_memory_t *mem = pdev->pdf_memory;
658     long *ids;
659 
660     ids = (long *)gs_alloc_byte_array(mem, pmht->num_comp, sizeof(long),
661 				      "pdf_write_multiple_halftone");
662     if (ids == 0)
663 	return_error(gs_error_VMerror);
664     for (i = 0; i < pmht->num_comp; ++i) {
665 	const gs_halftone_component *const phtc = &pmht->components[i];
666 	const gx_ht_order *porder =
667 	    (pdht->components == 0 ? &pdht->order :
668 	     &pdht->components[i].corder);
669 
670 	switch (phtc->type) {
671 	case ht_type_spot:
672 	    code = pdf_write_spot_halftone(pdev, &phtc->params.spot,
673 					   porder, &ids[i]);
674 	    break;
675 	case ht_type_threshold:
676 	    code = pdf_write_threshold_halftone(pdev, &phtc->params.threshold,
677 						porder, &ids[i]);
678 	    break;
679 	case ht_type_threshold2:
680 	    code = pdf_write_threshold2_halftone(pdev,
681 						 &phtc->params.threshold2,
682 						 porder, &ids[i]);
683 	    break;
684 	default:
685 	    code = gs_note_error(gs_error_rangecheck);
686 	}
687 	if (code < 0) {
688 	    gs_free_object(mem, ids, "pdf_write_multiple_halftone");
689 	    return code;
690 	}
691     }
692     *pid = pdf_begin_separate(pdev);
693     s = pdev->strm;
694     stream_puts(s, "<</Type/Halftone/HalftoneType 5\n");
695     for (i = 0; i < pmht->num_comp; ++i) {
696 	const gs_halftone_component *const phtc = &pmht->components[i];
697 	cos_value_t value;
698 
699 	code = pdf_separation_name(pdev, &value, phtc->cname);
700 	if (code < 0)
701 	    return code;
702 	cos_value_write(&value, pdev);
703 	gs_free_string(mem, value.contents.chars.data,
704 		       value.contents.chars.size,
705 		       "pdf_write_multiple_halftone");
706 	pprintld1(s, " %ld 0 R\n", ids[i]);
707     }
708     stream_puts(s, ">>\n");
709     gs_free_object(mem, ids, "pdf_write_multiple_halftone");
710     return pdf_end_separate(pdev);
711 }
712 
713 /*
714  * Update the halftone.  This is a separate procedure only for
715  * readability.
716  */
717 private int
pdf_update_halftone(gx_device_pdf * pdev,const gs_imager_state * pis,char * hts)718 pdf_update_halftone(gx_device_pdf *pdev, const gs_imager_state *pis,
719 		    char *hts)
720 {
721     const gs_halftone *pht = pis->halftone;
722     const gx_device_halftone *pdht = pis->dev_ht;
723     int code;
724     long id;
725 
726     switch (pht->type) {
727     case ht_type_screen:
728 	code = pdf_write_screen_halftone(pdev, &pht->params.screen,
729 					 &pdht->order, &id);
730 	break;
731     case ht_type_colorscreen:
732 	code = pdf_write_colorscreen_halftone(pdev, &pht->params.colorscreen,
733 					      pdht, &id);
734 	break;
735     case ht_type_spot:
736 	code = pdf_write_spot_halftone(pdev, &pht->params.spot,
737 				       &pdht->order, &id);
738 	break;
739     case ht_type_threshold:
740 	code = pdf_write_threshold_halftone(pdev, &pht->params.threshold,
741 					    &pdht->order, &id);
742 	break;
743     case ht_type_threshold2:
744 	code = pdf_write_threshold2_halftone(pdev, &pht->params.threshold2,
745 					     &pdht->order, &id);
746 	break;
747     case ht_type_multiple:
748     case ht_type_multiple_colorscreen:
749 	code = pdf_write_multiple_halftone(pdev, &pht->params.multiple,
750 					   pdht, &id);
751 	break;
752     default:
753 	return_error(gs_error_rangecheck);
754     }
755     if (code < 0)
756 	return code;
757     sprintf(hts, "/HT %ld 0 R", id);
758     pdev->halftone_id = pis->dev_ht->id;
759     return code;
760 }
761 
762 /* ------ Graphics state updating ------ */
763 
764 /* Open an ExtGState. */
765 private int
pdf_open_gstate(gx_device_pdf * pdev,pdf_resource_t ** ppres)766 pdf_open_gstate(gx_device_pdf *pdev, pdf_resource_t **ppres)
767 {
768     if (*ppres)
769 	return 0;
770     return pdf_begin_resource(pdev, resourceExtGState, gs_no_id, ppres);
771 }
772 
773 /* Finish writing an ExtGState. */
774 private int
pdf_end_gstate(gx_device_pdf * pdev,pdf_resource_t * pres)775 pdf_end_gstate(gx_device_pdf *pdev, pdf_resource_t *pres)
776 {
777     if (pres) {
778 	int code;
779 
780 	stream_puts(pdev->strm, ">>\n");
781 	code = pdf_end_resource(pdev);
782 	pres->object->written = true; /* don't write at end of page */
783 	if (code < 0)
784 	    return code;
785 	code = pdf_open_page(pdev, PDF_IN_STREAM);
786 	if (code < 0)
787 	    return code;
788 	pprintld1(pdev->strm, "/R%ld gs\n", pdf_resource_id(pres));
789     }
790     return 0;
791 }
792 
793 /*
794  * Update the transfer functions(s).  This is a separate procedure only
795  * for readability.
796  */
797 private int
pdf_update_transfer(gx_device_pdf * pdev,const gs_imager_state * pis,char * trs)798 pdf_update_transfer(gx_device_pdf *pdev, const gs_imager_state *pis,
799 		    char *trs)
800 {
801     int i;
802     bool multiple = false, update = false;
803     gs_id transfer_ids[4];
804     int code = 0;
805 
806     for (i = 0; i < 4; ++i) {
807 	transfer_ids[i] = pis->set_transfer.indexed[i]->id;
808 	if (pdev->transfer_ids[i] != transfer_ids[i])
809 	    update = true;
810 	if (transfer_ids[i] != transfer_ids[0])
811 	    multiple = true;
812     }
813     if (update) {
814 	int mask;
815 
816 	if (!multiple) {
817 	    code = pdf_write_transfer(pdev, pis->set_transfer.indexed[0],
818 				      "/TR", trs);
819 	    if (code < 0)
820 		return code;
821 	    mask = code == 0;
822 	} else {
823 	    strcpy(trs, "/TR[");
824 	    mask = 0;
825 	    for (i = 0; i < 4; ++i) {
826 		code = pdf_write_transfer_map(pdev,
827 					      pis->set_transfer.indexed[i],
828 					      0, false, "", trs + strlen(trs));
829 		if (code < 0)
830 		    return code;
831 		mask |= (code == 0) << i;
832 	    }
833 	    strcat(trs, "]");
834 	}
835 	memcpy(pdev->transfer_ids, transfer_ids, sizeof(pdev->transfer_ids));
836 	pdev->transfer_not_identity = mask;
837     }
838     return code;
839 }
840 
841 /*
842  * Update the current alpha if necessary.  Note that because Ghostscript
843  * stores separate opacity and shape alpha, a rangecheck will occur if
844  * both are different from the current setting.
845  */
846 private int
pdf_update_alpha(gx_device_pdf * pdev,const gs_imager_state * pis,const char * ca_format,pdf_resource_t ** ppres)847 pdf_update_alpha(gx_device_pdf *pdev, const gs_imager_state *pis,
848 		 const char *ca_format, pdf_resource_t **ppres)
849 {
850     bool ais;
851     floatp alpha;
852     int code;
853 
854     if (pdev->state.opacity.alpha != pis->opacity.alpha) {
855 	if (pdev->state.shape.alpha != pis->shape.alpha)
856 	    return_error(gs_error_rangecheck);
857 	ais = false;
858 	alpha = pdev->state.opacity.alpha = pis->opacity.alpha;
859     } else if (pdev->state.shape.alpha != pis->shape.alpha) {
860 	ais = true;
861 	alpha = pdev->state.shape.alpha = pis->shape.alpha;
862     } else
863 	return 0;
864     code = pdf_open_gstate(pdev, ppres);
865     if (code < 0)
866 	return code;
867     pprintb1(pdev->strm, "/AIS %s", ais);
868     pprintg1(pdev->strm, ca_format, alpha);
869     return 0;
870 }
871 
872 /*
873  * Update the graphics subset common to all high-level drawing operations.
874  */
875 private int
pdf_prepare_drawing(gx_device_pdf * pdev,const gs_imager_state * pis,const char * ca_format,pdf_resource_t ** ppres)876 pdf_prepare_drawing(gx_device_pdf *pdev, const gs_imager_state *pis,
877 		    const char *ca_format, pdf_resource_t **ppres)
878 {
879     int code = 0;
880 
881     if (pdev->CompatibilityLevel >= 1.4) {
882 	if (pdev->state.blend_mode != pis->blend_mode) {
883 	    static const char *const bm_names[] = { GS_BLEND_MODE_NAMES };
884 
885 	    code = pdf_open_gstate(pdev, ppres);
886 	    if (code < 0)
887 		return code;
888 	    pprints1(pdev->strm, "/BM/%s", bm_names[pis->blend_mode]);
889 	    pdev->state.blend_mode = pis->blend_mode;
890 	}
891 	code = pdf_update_alpha(pdev, pis, ca_format, ppres);
892 	if (code < 0)
893 	    return code;
894     } else {
895 	/*
896 	 * If the graphics state calls for any transparency functions,
897 	 * we can't represent them, so return a rangecheck.
898 	 */
899 	if (pis->opacity.alpha != 1 || pis->opacity.mask != 0 ||
900 	    pis->shape.alpha != 1 || pis->shape.mask != 0 ||
901 	    pis->transparency_stack != 0
902 	    )
903 	    return_error(gs_error_rangecheck);
904     }
905     /*
906      * We originally thought the remaining items were only needed for
907      * fill and stroke, but in fact they are needed for images as well.
908      */
909     /*
910      * Update halftone, transfer function, black generation, undercolor
911      * removal, halftone phase, overprint mode, smoothness, blend mode, text
912      * knockout.
913      */
914     if (pdev->CompatibilityLevel >= 1.2) {
915 	gs_int_point phase, dev_phase;
916 	char hts[5 + MAX_FN_CHARS + 1],
917 	    trs[5 + MAX_FN_CHARS * 4 + 6 + 1],
918 	    bgs[5 + MAX_FN_CHARS + 1],
919 	    ucrs[6 + MAX_FN_CHARS + 1];
920 
921 	hts[0] = trs[0] = bgs[0] = ucrs[0] = 0;
922 	if (pdev->params.PreserveHalftoneInfo &&
923 	    pdev->halftone_id != pis->dev_ht->id
924 	    ) {
925 	    code = pdf_update_halftone(pdev, pis, hts);
926 	    if (code < 0)
927 		return code;
928 	}
929 	if (pdev->params.TransferFunctionInfo == tfi_Preserve) {
930 	    code = pdf_update_transfer(pdev, pis, trs);
931 	    if (code < 0)
932 		return code;
933 	}
934 	if (pdev->params.UCRandBGInfo == ucrbg_Preserve) {
935 	    if (pdev->black_generation_id != pis->black_generation->id) {
936 		code = pdf_write_transfer_map(pdev, pis->black_generation,
937 					      0, false, "/BG", bgs);
938 		if (code < 0)
939 		    return code;
940 		pdev->black_generation_id = pis->black_generation->id;
941 	    }
942 	    if (pdev->undercolor_removal_id != pis->undercolor_removal->id) {
943 		code = pdf_write_transfer_map(pdev, pis->undercolor_removal,
944 					      -1, false, "/UCR", ucrs);
945 		if (code < 0)
946 		    return code;
947 		pdev->undercolor_removal_id = pis->undercolor_removal->id;
948 	    }
949 	}
950 	if (hts[0] || trs[0] || bgs[0] || ucrs[0]) {
951 	    code = pdf_open_gstate(pdev, ppres);
952 	    if (code < 0)
953 		return code;
954 	    stream_puts(pdev->strm, hts);
955 	    stream_puts(pdev->strm, trs);
956 	    stream_puts(pdev->strm, bgs);
957 	    stream_puts(pdev->strm, ucrs);
958 	}
959 	gs_currenthalftonephase((const gs_state *)pis, &phase);
960 	gs_currenthalftonephase((const gs_state *)&pdev->state, &dev_phase);
961 	if (dev_phase.x != phase.x || dev_phase.y != phase.y) {
962 	    code = pdf_open_gstate(pdev, ppres);
963 	    if (code < 0)
964 		return code;
965 	    pprintd2(pdev->strm, "/HTP[%d %d]", phase.x, phase.y);
966 	    gx_imager_setscreenphase(&pdev->state, phase.x, phase.y,
967 				     gs_color_select_all);
968 	}
969     }
970     if (pdev->CompatibilityLevel >= 1.3) {
971 	if (pdev->overprint_mode != pdev->params.OPM) {
972 	    code = pdf_open_gstate(pdev, ppres);
973 	    if (code < 0)
974 		return code;
975 	    pprintd1(pdev->strm, "/OPM %d", pdev->params.OPM);
976 	    pdev->overprint_mode = pdev->params.OPM;
977 	}
978 	if (pdev->state.smoothness != pis->smoothness) {
979 	    code = pdf_open_gstate(pdev, ppres);
980 	    if (code < 0)
981 		return code;
982 	    pprintg1(pdev->strm, "/SM %g", pis->smoothness);
983 	    pdev->state.smoothness = pis->smoothness;
984 	}
985 	if (pdev->CompatibilityLevel >= 1.4) {
986 	    if (pdev->state.text_knockout != pis->text_knockout) {
987 		code = pdf_open_gstate(pdev, ppres);
988 		if (code < 0)
989 		    return code;
990 		pprintb1(pdev->strm, "/TK %s", pis->text_knockout);
991 		pdev->state.text_knockout = pis->text_knockout;
992 	    }
993 	}
994     }
995     return code;
996 }
997 
998 /* Update the graphics state for filling. */
999 int
pdf_prepare_fill(gx_device_pdf * pdev,const gs_imager_state * pis)1000 pdf_prepare_fill(gx_device_pdf *pdev, const gs_imager_state *pis)
1001 {
1002     pdf_resource_t *pres = 0;
1003     int code = pdf_prepare_drawing(pdev, pis, "/ca %g", &pres);
1004 
1005     if (code < 0)
1006 	return code;
1007     /* Update overprint. */
1008     if (pdev->CompatibilityLevel >= 1.2) {
1009 	if (pdev->params.PreserveOverprintSettings &&
1010 	    pdev->fill_overprint != pis->overprint
1011 	    ) {
1012 	    code = pdf_open_gstate(pdev, &pres);
1013 	    if (code < 0)
1014 		return code;
1015 	    /* PDF 1.2 only has a single overprint setting. */
1016 	    if (pdev->CompatibilityLevel < 1.3) {
1017 		pprintb1(pdev->strm, "/OP %s", pis->overprint);
1018 		pdev->stroke_overprint = pis->overprint;
1019 	    } else {
1020 		pprintb1(pdev->strm, "/op %s", pis->overprint);
1021 	    }
1022 	    pdev->fill_overprint = pis->overprint;
1023 	}
1024     }
1025     return pdf_end_gstate(pdev, pres);
1026 }
1027 
1028 /* Update the graphics state for stroking. */
1029 int
pdf_prepare_stroke(gx_device_pdf * pdev,const gs_imager_state * pis)1030 pdf_prepare_stroke(gx_device_pdf *pdev, const gs_imager_state *pis)
1031 {
1032     pdf_resource_t *pres = 0;
1033     int code = pdf_prepare_drawing(pdev, pis, "/CA %g", &pres);
1034 
1035     if (code < 0)
1036 	return code;
1037     /* Update overprint, stroke adjustment. */
1038     if (pdev->CompatibilityLevel >= 1.2) {
1039 	if (pdev->params.PreserveOverprintSettings &&
1040 	    pdev->stroke_overprint != pis->overprint
1041 	    ) {
1042 	    code = pdf_open_gstate(pdev, &pres);
1043 	    if (code < 0)
1044 		return code;
1045 	    pprintb1(pdev->strm, "/OP %s", pis->overprint);
1046 	    pdev->stroke_overprint = pis->overprint;
1047 	    /* PDF 1.2 only has a single overprint setting. */
1048 	    if (pdev->CompatibilityLevel < 1.3)
1049 		pdev->fill_overprint = pis->overprint;
1050 	}
1051 	if (pdev->state.stroke_adjust != pis->stroke_adjust) {
1052 	    code = pdf_open_gstate(pdev, &pres);
1053 	    if (code < 0)
1054 		return code;
1055 	    pprintb1(pdev->strm, "/SA %s", pis->stroke_adjust);
1056 	    pdev->state.stroke_adjust = pis->stroke_adjust;
1057 	}
1058     }
1059     return pdf_end_gstate(pdev, pres);
1060 }
1061 
1062 /* Update the graphics state for an image other than an ImageType 1 mask. */
1063 int
pdf_prepare_image(gx_device_pdf * pdev,const gs_imager_state * pis)1064 pdf_prepare_image(gx_device_pdf *pdev, const gs_imager_state *pis)
1065 {
1066     pdf_resource_t *pres = 0;
1067     int code = pdf_prepare_drawing(pdev, pis, "/ca %g", &pres);
1068 
1069     if (code < 0)
1070 	return code;
1071     return pdf_end_gstate(pdev, pres);
1072 }
1073 
1074 /* Update the graphics state for an ImageType 1 mask. */
1075 int
pdf_prepare_imagemask(gx_device_pdf * pdev,const gs_imager_state * pis,const gx_drawing_color * pdcolor)1076 pdf_prepare_imagemask(gx_device_pdf *pdev, const gs_imager_state *pis,
1077 		      const gx_drawing_color *pdcolor)
1078 {
1079     int code = pdf_prepare_image(pdev, pis);
1080 
1081     if (code < 0)
1082 	return code;
1083     return pdf_set_drawing_color(pdev, pdcolor, &pdev->fill_color,
1084 				 &psdf_set_fill_color_commands);
1085 }
1086