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, ¶ms, 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(¶ms.DataSource, (const byte *)values,
469 sizeof(*values) * num_bits);
470 if (code >= 0 &&
471 (code = gs_function_Sd_init(&pfn, ¶ms, 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