gdevpdfg.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597
  1. /* Copyright (C) 1999, 2000, 2001 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gdevpdfg.c,v 1.68 2005/09/12 11:34:50 leonardo Exp $ */
  14. /* Graphics state management for pdfwrite driver */
  15. #include "math_.h"
  16. #include "string_.h"
  17. #include "memory_.h"
  18. #include "gx.h"
  19. #include "gserrors.h"
  20. #include "gsfunc0.h"
  21. #include "gsstate.h"
  22. #include "gxbitmap.h" /* for gxhttile.h in gzht.h */
  23. #include "gxdht.h"
  24. #include "gxfarith.h" /* for gs_sin/cos_degrees */
  25. #include "gxfmap.h"
  26. #include "gxht.h"
  27. #include "gxistate.h"
  28. #include "gxdcolor.h"
  29. #include "gxpcolor.h"
  30. #include "gsptype2.h"
  31. #include "gzht.h"
  32. #include "gdevpdfx.h"
  33. #include "gdevpdfg.h"
  34. #include "gdevpdfo.h"
  35. #include "szlibx.h"
  36. /* ---------------- Miscellaneous ---------------- */
  37. /* Save the viewer's graphic state. */
  38. int
  39. pdf_save_viewer_state(gx_device_pdf *pdev, stream *s)
  40. {
  41. const int i = pdev->vgstack_depth;
  42. if (pdev->vgstack_depth >= count_of(pdev->vgstack))
  43. return_error(gs_error_unregistered); /* Must not happen. */
  44. pdev->vgstack[i].transfer_ids[0] = pdev->transfer_ids[0];
  45. pdev->vgstack[i].transfer_ids[1] = pdev->transfer_ids[1];
  46. pdev->vgstack[i].transfer_ids[2] = pdev->transfer_ids[2];
  47. pdev->vgstack[i].transfer_ids[3] = pdev->transfer_ids[3];
  48. pdev->vgstack[i].transfer_not_identity = pdev->transfer_not_identity;
  49. pdev->vgstack[i].opacity_alpha = pdev->state.opacity.alpha;
  50. pdev->vgstack[i].shape_alpha = pdev->state.shape.alpha;
  51. pdev->vgstack[i].blend_mode = pdev->state.blend_mode;
  52. pdev->vgstack[i].halftone_id = pdev->halftone_id;
  53. pdev->vgstack[i].black_generation_id = pdev->black_generation_id;
  54. pdev->vgstack[i].undercolor_removal_id = pdev->undercolor_removal_id;
  55. pdev->vgstack[i].overprint_mode = pdev->overprint_mode;
  56. pdev->vgstack[i].smoothness = pdev->state.smoothness;
  57. pdev->vgstack[i].flatness = pdev->state.flatness;
  58. pdev->vgstack[i].text_knockout = pdev->state.text_knockout;
  59. pdev->vgstack[i].fill_overprint = pdev->fill_overprint;
  60. pdev->vgstack[i].stroke_overprint = pdev->stroke_overprint;
  61. pdev->vgstack[i].stroke_adjust = pdev->state.stroke_adjust;
  62. pdev->vgstack[i].fill_used_process_color = pdev->fill_used_process_color;
  63. pdev->vgstack[i].stroke_used_process_color = pdev->stroke_used_process_color;
  64. pdev->vgstack[i].saved_fill_color = pdev->saved_fill_color;
  65. pdev->vgstack[i].saved_stroke_color = pdev->saved_stroke_color;
  66. pdev->vgstack[i].line_params = pdev->state.line_params;
  67. pdev->vgstack[i].line_params.dash.pattern = 0; /* Use pdev->dash_pattern instead. */
  68. memcpy(pdev->vgstack[i].dash_pattern, pdev->dash_pattern,
  69. sizeof(pdev->vgstack[i].dash_pattern));
  70. pdev->vgstack_depth++;
  71. if (s)
  72. stream_puts(s, "q\n");
  73. return 0;
  74. }
  75. /* Load the viewer's graphic state. */
  76. private void
  77. pdf_load_viewer_state(gx_device_pdf *pdev, pdf_viewer_state *s)
  78. {
  79. pdev->transfer_ids[0] = s->transfer_ids[0];
  80. pdev->transfer_ids[1] = s->transfer_ids[1];
  81. pdev->transfer_ids[2] = s->transfer_ids[2];
  82. pdev->transfer_ids[3] = s->transfer_ids[3];
  83. pdev->transfer_not_identity = s->transfer_not_identity;
  84. pdev->state.opacity.alpha = s->opacity_alpha;
  85. pdev->state.shape.alpha = s->shape_alpha;
  86. pdev->state.blend_mode = s->blend_mode;
  87. pdev->halftone_id = s->halftone_id;
  88. pdev->black_generation_id = s->black_generation_id;
  89. pdev->undercolor_removal_id = s->undercolor_removal_id;
  90. pdev->overprint_mode = s->overprint_mode;
  91. pdev->state.smoothness = s->smoothness;
  92. pdev->state.flatness = s->flatness;
  93. pdev->state.text_knockout = s->text_knockout;
  94. pdev->fill_overprint = s->fill_overprint;
  95. pdev->stroke_overprint = s->stroke_overprint;
  96. pdev->state.stroke_adjust = s->stroke_adjust;
  97. pdev->fill_used_process_color = s->fill_used_process_color;
  98. pdev->stroke_used_process_color = s->stroke_used_process_color;
  99. pdev->saved_fill_color = s->saved_fill_color;
  100. pdev->saved_stroke_color = s->saved_stroke_color;
  101. pdev->state.line_params = s->line_params;
  102. memcpy(pdev->dash_pattern, s->dash_pattern,
  103. sizeof(s->dash_pattern));
  104. }
  105. /* Restore the viewer's graphic state. */
  106. int
  107. pdf_restore_viewer_state(gx_device_pdf *pdev, stream *s)
  108. { const int i = --pdev->vgstack_depth;
  109. if (i < pdev->vgstack_bottom || i < 0)
  110. return_error(gs_error_unregistered); /* Must not happen. */
  111. if (s)
  112. stream_puts(s, "Q\n");
  113. pdf_load_viewer_state(pdev, pdev->vgstack + i);
  114. return 0;
  115. }
  116. /* Set initial color. */
  117. void
  118. pdf_set_initial_color(gx_device_pdf * pdev, gx_hl_saved_color *saved_fill_color,
  119. gx_hl_saved_color *saved_stroke_color,
  120. bool *fill_used_process_color, bool *stroke_used_process_color)
  121. {
  122. gx_device_color black;
  123. pdev->black = gx_device_black((gx_device *)pdev);
  124. pdev->white = gx_device_white((gx_device *)pdev);
  125. set_nonclient_dev_color(&black, pdev->black);
  126. gx_hld_save_color(NULL, &black, saved_fill_color);
  127. gx_hld_save_color(NULL, &black, saved_stroke_color);
  128. *fill_used_process_color = true;
  129. *stroke_used_process_color = true;
  130. }
  131. /* Prepare intitial values for viewer's graphics state parameters. */
  132. private void
  133. pdf_viewer_state_from_imager_state_aux(pdf_viewer_state *pvs, const gs_imager_state *pis)
  134. {
  135. pvs->transfer_not_identity =
  136. (pis->set_transfer.red != NULL ? pis->set_transfer.red->proc != gs_identity_transfer : 0) * 1 +
  137. (pis->set_transfer.green != NULL ? pis->set_transfer.green->proc != gs_identity_transfer : 0) * 2 +
  138. (pis->set_transfer.blue != NULL ? pis->set_transfer.blue->proc != gs_identity_transfer : 0) * 4 +
  139. (pis->set_transfer.gray != NULL ? pis->set_transfer.gray->proc != gs_identity_transfer : 0) * 8;
  140. pvs->transfer_ids[0] = (pis->set_transfer.red != NULL ? pis->set_transfer.red->id : 0);
  141. pvs->transfer_ids[1] = (pis->set_transfer.green != NULL ? pis->set_transfer.green->id : 0);
  142. pvs->transfer_ids[2] = (pis->set_transfer.blue != NULL ? pis->set_transfer.blue->id : 0);
  143. pvs->transfer_ids[3] = (pis->set_transfer.gray != NULL ? pis->set_transfer.gray->id : 0);
  144. pvs->opacity_alpha = pis->opacity.alpha;
  145. pvs->shape_alpha = pis->shape.alpha;
  146. pvs->blend_mode = pis->blend_mode;
  147. pvs->halftone_id = (pis->dev_ht != 0 ? pis->dev_ht->id : 0);
  148. pvs->black_generation_id = (pis->black_generation != 0 ? pis->black_generation->id : 0);
  149. pvs->undercolor_removal_id = (pis->undercolor_removal != 0 ? pis->undercolor_removal->id : 0);
  150. pvs->overprint_mode = 0;
  151. pvs->smoothness = pis->smoothness;
  152. pvs->text_knockout = pis->text_knockout;
  153. pvs->fill_overprint = false;
  154. pvs->stroke_overprint = false;
  155. pvs->stroke_adjust = false;
  156. pvs->line_params.half_width = 0.5;
  157. pvs->line_params.cap = 0;
  158. pvs->line_params.join = 0;
  159. pvs->line_params.curve_join = 0;
  160. pvs->line_params.miter_limit = 10.0;
  161. pvs->line_params.miter_check = 0;
  162. pvs->line_params.dot_length = pis->line_params.dot_length;
  163. pvs->line_params.dot_length_absolute = pis->line_params.dot_length_absolute;
  164. pvs->line_params.dot_orientation = pis->line_params.dot_orientation;
  165. memset(&pvs->line_params.dash, 0 , sizeof(pvs->line_params.dash));
  166. memset(pvs->dash_pattern, 0, sizeof(pvs->dash_pattern));
  167. }
  168. /* Copy viewer state from images state. */
  169. void
  170. pdf_viewer_state_from_imager_state(gx_device_pdf * pdev,
  171. const gs_imager_state *pis, const gx_device_color *pdevc)
  172. {
  173. pdf_viewer_state vs;
  174. pdf_viewer_state_from_imager_state_aux(&vs, pis);
  175. gx_hld_save_color(pis, pdevc, &vs.saved_fill_color);
  176. gx_hld_save_color(pis, pdevc, &vs.saved_stroke_color);
  177. pdf_load_viewer_state(pdev, &vs);
  178. }
  179. /* Prepare intitial values for viewer's graphics state parameters. */
  180. void
  181. pdf_prepare_initial_viewer_state(gx_device_pdf * pdev, const gs_imager_state *pis)
  182. {
  183. /* Parameter values, which are specified in PDF spec, are set here.
  184. * Parameter values, which are specified in PDF spec as "installation dependent",
  185. * are set here to intial values used with PS interpreter.
  186. * This allows to write differences to the output file
  187. * and skip initial values.
  188. */
  189. pdf_set_initial_color(pdev, &pdev->vg_initial.saved_fill_color, &pdev->vg_initial.saved_stroke_color,
  190. &pdev->vg_initial.fill_used_process_color, &pdev->vg_initial.stroke_used_process_color);
  191. pdf_viewer_state_from_imager_state_aux(&pdev->vg_initial, pis);
  192. pdev->vg_initial_set = true;
  193. /*
  194. * Some parameters listed in PDF spec are missed here :
  195. * text state - it is initialized per page.
  196. * rendering intent - not sure why, fixme.
  197. */
  198. }
  199. /* Reset the graphics state parameters to initial values. */
  200. /* Used if pdf_prepare_initial_viewer_state was not callad. */
  201. private void
  202. pdf_reset_graphics_old(gx_device_pdf * pdev)
  203. {
  204. pdf_set_initial_color(pdev, &pdev->saved_fill_color, &pdev->saved_stroke_color,
  205. &pdev->fill_used_process_color, &pdev->stroke_used_process_color);
  206. pdev->state.flatness = -1;
  207. {
  208. static const gx_line_params lp_initial = {
  209. gx_line_params_initial
  210. };
  211. pdev->state.line_params = lp_initial;
  212. }
  213. pdev->fill_overprint = false;
  214. pdev->stroke_overprint = false;
  215. pdf_reset_text(pdev);
  216. }
  217. /* Reset the graphics state parameters to initial values. */
  218. void
  219. pdf_reset_graphics(gx_device_pdf * pdev)
  220. {
  221. if (pdev->vg_initial_set)
  222. pdf_load_viewer_state(pdev, &pdev->vg_initial);
  223. else
  224. pdf_reset_graphics_old(pdev);
  225. pdf_reset_text(pdev);
  226. }
  227. /* Write client color. */
  228. private int
  229. pdf_write_ccolor(gx_device_pdf * pdev, const gs_imager_state * pis,
  230. const gs_client_color *pcc)
  231. {
  232. int i, n = gx_hld_get_number_color_components(pis);
  233. pprintg1(pdev->strm, "%g", psdf_round(pcc->paint.values[0], 255, 8));
  234. for (i = 1; i < n; i++) {
  235. pprintg1(pdev->strm, " %g", psdf_round(pcc->paint.values[i], 255, 8));
  236. }
  237. return 0;
  238. }
  239. /* Set the fill or stroke color. */
  240. private int
  241. pdf_reset_color(gx_device_pdf * pdev, const gs_imager_state * pis,
  242. const gx_drawing_color *pdc, gx_hl_saved_color * psc,
  243. bool *used_process_color,
  244. const psdf_set_color_commands_t *ppscc)
  245. {
  246. int code;
  247. gx_hl_saved_color temp;
  248. bool process_color;
  249. const gs_color_space *pcs, *pcs2;
  250. const gs_client_color *pcc; /* fixme: not needed due to gx_hld_get_color_component. */
  251. cos_value_t cs_value;
  252. const char *command;
  253. int code1 = 0;
  254. gs_color_space_index csi;
  255. if (pdev->skip_colors)
  256. return 0;
  257. process_color = !gx_hld_save_color(pis, pdc, &temp);
  258. /* Since pdfwrite never applies halftones and patterns, but monitors
  259. * halftone/pattern IDs separately, we don't need to compare
  260. * halftone/pattern bodies here.
  261. */
  262. if (gx_hld_saved_color_equal(&temp, psc))
  263. return 0;
  264. /*
  265. * In principle, we can set colors in either stream or text
  266. * context. However, since we currently enclose all text
  267. * strings inside a gsave/grestore, this causes us to lose
  268. * track of the color when we leave text context. Therefore,
  269. * we require stream context for setting colors.
  270. */
  271. code = pdf_open_page(pdev, PDF_IN_STREAM);
  272. if (code < 0)
  273. return code;
  274. switch (gx_hld_get_color_space_and_ccolor(pis, pdc, &pcs, &pcc)) {
  275. case non_pattern_color_space:
  276. switch (gs_color_space_get_index(pcs)) {
  277. case gs_color_space_index_DeviceGray:
  278. command = ppscc->setgray;
  279. break;
  280. case gs_color_space_index_DeviceRGB:
  281. command = ppscc->setrgbcolor;
  282. break;
  283. case gs_color_space_index_DeviceCMYK:
  284. command = ppscc->setcmykcolor;
  285. break;
  286. case gs_color_space_index_Indexed:
  287. if (pdev->CompatibilityLevel <= 1.2) {
  288. pcs2 = (const gs_color_space *)&pcs->params.indexed.base_space;
  289. csi = gs_color_space_get_index(pcs2);
  290. if (csi == gs_color_space_index_Separation) {
  291. pcs2 = (const gs_color_space *)&pcs2->params.separation.alt_space;
  292. goto check_pcs2;
  293. }
  294. goto check_pcs2;
  295. }
  296. goto scn;
  297. case gs_color_space_index_Separation:
  298. if (pdev->CompatibilityLevel <= 1.2) {
  299. pcs2 = (const gs_color_space *)&pcs->params.separation.alt_space;
  300. check_pcs2:
  301. csi = gs_color_space_get_index(pcs2);
  302. switch(gs_color_space_get_index(pcs2)) {
  303. case gs_color_space_index_DevicePixel :
  304. case gs_color_space_index_DeviceN:
  305. case gs_color_space_index_CIEICC:
  306. goto write_process_color;
  307. default:
  308. DO_NOTHING;
  309. }
  310. }
  311. goto scn;
  312. case gs_color_space_index_CIEICC:
  313. case gs_color_space_index_DevicePixel:
  314. case gs_color_space_index_DeviceN:
  315. if (pdev->CompatibilityLevel <= 1.2)
  316. goto write_process_color;
  317. goto scn;
  318. default :
  319. scn:
  320. command = ppscc->setcolorn;
  321. if (!gx_hld_saved_color_same_cspace(&temp, psc)) {
  322. code = pdf_color_space(pdev, &cs_value, NULL, pcs,
  323. &pdf_color_space_names, true);
  324. /* fixme : creates redundant PDF objects. */
  325. if (code == gs_error_rangecheck) {
  326. /* The color space can't write to PDF. */
  327. goto write_process_color;
  328. }
  329. if (code < 0)
  330. return code;
  331. code = cos_value_write(&cs_value, pdev);
  332. if (code < 0)
  333. return code;
  334. pprints1(pdev->strm, " %s\n", ppscc->setcolorspace);
  335. } else if (*used_process_color)
  336. goto write_process_color;
  337. break;
  338. }
  339. *used_process_color = false;
  340. code = pdf_write_ccolor(pdev, pis, pcc);
  341. if (code < 0)
  342. return code;
  343. pprints1(pdev->strm, " %s\n", command);
  344. break;
  345. case pattern_color_sapce:
  346. { pdf_resource_t *pres;
  347. if (pdc->type == gx_dc_type_pattern)
  348. code = pdf_put_colored_pattern(pdev, pdc, pcs,
  349. ppscc, pis->have_pattern_streams, &pres);
  350. else if (pdc->type == &gx_dc_pure_masked) {
  351. code = pdf_put_uncolored_pattern(pdev, pdc, pcs,
  352. ppscc, pis->have_pattern_streams, &pres);
  353. if (code < 0 || pres == 0)
  354. return code;
  355. if (pis->have_pattern_streams)
  356. code = pdf_write_ccolor(pdev, pis, pcc);
  357. } else if (pdc->type == &gx_dc_pattern2) {
  358. if (pdev->CompatibilityLevel <= 1.2)
  359. return_error(gs_error_rangecheck);
  360. code1 = pdf_put_pattern2(pdev, pdc, ppscc, &pres);
  361. } else
  362. return_error(gs_error_rangecheck);
  363. if (code < 0)
  364. return code;
  365. cos_value_write(cos_resource_value(&cs_value, pres->object), pdev);
  366. pprints1(pdev->strm, " %s\n", ppscc->setcolorn);
  367. code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
  368. if (code < 0)
  369. return code;
  370. }
  371. *used_process_color = false;
  372. break;
  373. default: /* must not happen. */
  374. case use_process_color:
  375. write_process_color:
  376. code = psdf_set_color((gx_device_vector *)pdev, pdc, ppscc);
  377. if (code < 0)
  378. return code;
  379. *used_process_color = true;
  380. }
  381. *psc = temp;
  382. return code1;
  383. }
  384. int
  385. pdf_set_drawing_color(gx_device_pdf * pdev, const gs_imager_state * pis,
  386. const gx_drawing_color *pdc,
  387. gx_hl_saved_color * psc,
  388. bool *used_process_color,
  389. const psdf_set_color_commands_t *ppscc)
  390. {
  391. return pdf_reset_color(pdev, pis, pdc, psc, used_process_color, ppscc);
  392. }
  393. int
  394. pdf_set_pure_color(gx_device_pdf * pdev, gx_color_index color,
  395. gx_hl_saved_color * psc,
  396. bool *used_process_color,
  397. const psdf_set_color_commands_t *ppscc)
  398. {
  399. gx_drawing_color dcolor;
  400. set_nonclient_dev_color(&dcolor, color);
  401. return pdf_reset_color(pdev, NULL, &dcolor, psc, used_process_color, ppscc);
  402. }
  403. /*
  404. * Convert a string into cos name.
  405. */
  406. int
  407. pdf_string_to_cos_name(gx_device_pdf *pdev, const byte *str, uint len,
  408. cos_value_t *pvalue)
  409. {
  410. byte *chars = gs_alloc_string(pdev->pdf_memory, len + 1,
  411. "pdf_string_to_cos_name");
  412. if (chars == 0)
  413. return_error(gs_error_VMerror);
  414. chars[0] = '/';
  415. memcpy(chars + 1, str, len);
  416. cos_string_value(pvalue, chars, len + 1);
  417. return 0;
  418. }
  419. /* ---------------- Graphics state updating ---------------- */
  420. /* ------ Functions ------ */
  421. /* Define the maximum size of a Function reference. */
  422. #define MAX_FN_NAME_CHARS 9 /* /Default, /Identity */
  423. #define MAX_FN_CHARS max(MAX_REF_CHARS + 4, MAX_FN_NAME_CHARS)
  424. /*
  425. * Create and write a Function for a gx_transfer_map. We use this for
  426. * transfer, BG, and UCR functions. If check_identity is true, check for
  427. * an identity map. Return 1 if the map is the identity map, otherwise
  428. * return 0.
  429. */
  430. private data_source_proc_access(transfer_map_access); /* check prototype */
  431. private int
  432. transfer_map_access(const gs_data_source_t *psrc, ulong start, uint length,
  433. byte *buf, const byte **ptr)
  434. {
  435. const gx_transfer_map *map = (const gx_transfer_map *)psrc->data.str.data;
  436. uint i;
  437. if (ptr)
  438. *ptr = buf;
  439. for (i = 0; i < length; ++i)
  440. buf[i] = frac2byte(map->values[(uint)start + i]);
  441. return 0;
  442. }
  443. private int
  444. transfer_map_access_signed(const gs_data_source_t *psrc,
  445. ulong start, uint length,
  446. byte *buf, const byte **ptr)
  447. {
  448. /* To prevent numeric errors, we need to map 0 to an integer.
  449. * We can't apply a general expression, because Decode isn't accessible here.
  450. * Assuming this works for UCR only.
  451. * Assuming the range of UCR is always [-1, 1].
  452. * Assuming BitsPerSample = 8.
  453. */
  454. const gx_transfer_map *map = (const gx_transfer_map *)psrc->data.str.data;
  455. uint i;
  456. *ptr = buf;
  457. for (i = 0; i < length; ++i)
  458. buf[i] = (byte)
  459. ((frac2float(map->values[(uint)start + i]) + 1) * 127);
  460. return 0;
  461. }
  462. private int
  463. pdf_write_transfer_map(gx_device_pdf *pdev, const gx_transfer_map *map,
  464. int range0, bool check_identity,
  465. const char *key, char *ids)
  466. {
  467. gs_memory_t *mem = pdev->pdf_memory;
  468. gs_function_Sd_params_t params;
  469. static const float domain01[2] = { 0, 1 };
  470. static const int size = transfer_map_size;
  471. float range01[2], decode[2];
  472. gs_function_t *pfn;
  473. long id;
  474. int code;
  475. if (map == 0) {
  476. *ids = 0; /* no map */
  477. return 1;
  478. }
  479. if (check_identity) {
  480. /* Check for an identity map. */
  481. int i;
  482. if (map->proc == gs_identity_transfer)
  483. i = transfer_map_size;
  484. else
  485. for (i = 0; i < transfer_map_size; ++i) {
  486. fixed d = map->values[i] - bits2frac(i, log2_transfer_map_size);
  487. if (any_abs(d) > fixed_epsilon) /* ignore small noise */
  488. break;
  489. }
  490. if (i == transfer_map_size) {
  491. strcpy(ids, key);
  492. strcat(ids, "/Identity");
  493. return 1;
  494. }
  495. }
  496. params.m = 1;
  497. params.Domain = domain01;
  498. params.n = 1;
  499. range01[0] = (float)range0, range01[1] = 1.0;
  500. params.Range = range01;
  501. params.Order = 1;
  502. params.DataSource.access =
  503. (range0 < 0 ? transfer_map_access_signed : transfer_map_access);
  504. params.DataSource.data.str.data = (const byte *)map; /* bogus */
  505. /* DataSource */
  506. params.BitsPerSample = 8; /* could be 16 */
  507. params.Encode = 0;
  508. if (range01[0] < 0 && range01[1] > 0) {
  509. /* This works for UCR only.
  510. * Map 0 to an integer.
  511. * Rather the range of UCR is always [-1, 1],
  512. * we prefer a general expression.
  513. */
  514. int r0 = (int)( -range01[0] * ((1 << params.BitsPerSample) - 1)
  515. / (range01[1] - range01[0]) ); /* Round down. */
  516. float r1 = r0 * range01[1] / -range01[0]; /* r0 + r1 <= (1 << params.BitsPerSample) - 1 */
  517. decode[0] = range01[0];
  518. decode[1] = range01[0] + (range01[1] - range01[0]) * ((1 << params.BitsPerSample) - 1)
  519. / (r0 + r1);
  520. params.Decode = decode;
  521. } else
  522. params.Decode = 0;
  523. params.Size = &size;
  524. code = gs_function_Sd_init(&pfn, &params, mem);
  525. if (code < 0)
  526. return code;
  527. code = pdf_write_function(pdev, pfn, &id);
  528. gs_function_free(pfn, false, mem);
  529. if (code < 0)
  530. return code;
  531. sprintf(ids, "%s%s%ld 0 R", key, (key[0] && key[0] != ' ' ? " " : ""), id);
  532. return 0;
  533. }
  534. private int
  535. pdf_write_transfer(gx_device_pdf *pdev, const gx_transfer_map *map,
  536. const char *key, char *ids)
  537. {
  538. return pdf_write_transfer_map(pdev, map, 0, true, key, ids);
  539. }
  540. /* ------ Halftones ------ */
  541. /*
  542. * Recognize the predefined PDF halftone functions. Note that because the
  543. * corresponding PostScript functions use single-precision floats, the
  544. * functions used for testing must do the same in order to get identical
  545. * results. Currently we only do this for a few of the functions.
  546. */
  547. #define HT_FUNC(name, expr)\
  548. private floatp name(floatp xd, floatp yd) {\
  549. float x = (float)xd, y = (float)yd;\
  550. return d2f(expr);\
  551. }
  552. /*
  553. * In most versions of gcc (e.g., 2.7.2.3, 2.95.4), return (float)xxx
  554. * doesn't actually do the coercion. Force this here. Note that if we
  555. * use 'inline', it doesn't work.
  556. */
  557. private float
  558. d2f(floatp d)
  559. {
  560. float f = (float)d;
  561. return f;
  562. }
  563. private floatp
  564. ht_Round(floatp xf, floatp yf)
  565. {
  566. float x = (float)xf, y = (float)yf;
  567. float xabs = fabs(x), yabs = fabs(y);
  568. if (d2f(xabs + yabs) <= 1)
  569. return d2f(1 - d2f(d2f(x * x) + d2f(y * y)));
  570. xabs -= 1, yabs -= 1;
  571. return d2f(d2f(d2f(xabs * xabs) + d2f(yabs * yabs)) - 1);
  572. }
  573. private floatp
  574. ht_Diamond(floatp xf, floatp yf)
  575. {
  576. float x = (float)xf, y = (float)yf;
  577. float xabs = fabs(x), yabs = fabs(y);
  578. if (d2f(xabs + yabs) <= 0.75)
  579. return d2f(1 - d2f(d2f(x * x) + d2f(y * y)));
  580. if (d2f(xabs + yabs) <= d2f(1.23))
  581. return d2f(1 - d2f(d2f(d2f(0.85) * xabs) + yabs));
  582. xabs -= 1, yabs -= 1;
  583. return d2f(d2f(d2f(xabs * xabs) + d2f(yabs * yabs)) - 1);
  584. }
  585. private floatp
  586. ht_Ellipse(floatp xf, floatp yf)
  587. {
  588. float x = (float)xf, y = (float)yf;
  589. float xabs = fabs(x), yabs = fabs(y);
  590. /*
  591. * The PDF Reference, 2nd edition, incorrectly specifies the
  592. * computation w = 4 * |x| + 3 * |y| - 3. The PostScript code in the
  593. * same book correctly implements w = 3 * |x| + 4 * |y| - 3.
  594. */
  595. float w = (float)(d2f(d2f(3 * xabs) + d2f(4 * yabs)) - 3);
  596. if (w < 0) {
  597. yabs /= 0.75;
  598. return d2f(1 - d2f((d2f(x * x) + d2f(yabs * yabs)) / 4));
  599. }
  600. if (w > 1) {
  601. xabs = 1 - xabs, yabs = d2f(1 - yabs) / 0.75;
  602. return d2f(d2f((d2f(xabs * xabs) + d2f(yabs * yabs)) / 4) - 1);
  603. }
  604. return d2f(0.5 - w);
  605. }
  606. /*
  607. * Most of these are recognized properly even without d2f. We've only
  608. * added d2f where it apparently makes a difference.
  609. */
  610. private float
  611. d2fsin_d(double x) {
  612. return d2f(gs_sin_degrees(d2f(x)));
  613. }
  614. private float
  615. d2fcos_d(double x) {
  616. return d2f(gs_cos_degrees(d2f(x)));
  617. }
  618. HT_FUNC(ht_EllipseA, 1 - (x * x + 0.9 * y * y))
  619. HT_FUNC(ht_InvertedEllipseA, x * x + 0.9 * y * y - 1)
  620. HT_FUNC(ht_EllipseB, 1 - sqrt(x * x + 0.625 * y * y))
  621. HT_FUNC(ht_EllipseC, 1 - (0.9 * x * x + y * y))
  622. HT_FUNC(ht_InvertedEllipseC, 0.9 * x * x + y * y - 1)
  623. HT_FUNC(ht_Line, -fabs((x - x) + y)) /* quiet compiler (unused variable x) */
  624. HT_FUNC(ht_LineX, (y - y) + x) /* quiet compiler (unused variable y) */
  625. HT_FUNC(ht_LineY, (x - x) + y) /* quiet compiler (unused variable x) */
  626. HT_FUNC(ht_Square, -max(fabs(x), fabs(y)))
  627. HT_FUNC(ht_Cross, -min(fabs(x), fabs(y)))
  628. HT_FUNC(ht_Rhomboid, (0.9 * fabs(x) + fabs(y)) / 2)
  629. HT_FUNC(ht_DoubleDot, (d2fsin_d(x * 360) + d2fsin_d(y * 360)) / 2)
  630. HT_FUNC(ht_InvertedDoubleDot, -(d2fsin_d(x * 360) + d2fsin_d(y * 360)) / 2)
  631. HT_FUNC(ht_SimpleDot, 1 - d2f(d2f(x * x) + d2f(y * y)))
  632. HT_FUNC(ht_InvertedSimpleDot, d2f(d2f(x * x) + d2f(y * y)) - 1)
  633. HT_FUNC(ht_CosineDot, (d2fcos_d(x * 180) + d2fcos_d(y * 180)) / 2)
  634. HT_FUNC(ht_Double, (d2fsin_d(x * 180) + d2fsin_d(y * 360)) / 2)
  635. HT_FUNC(ht_InvertedDouble, -(d2fsin_d(x * 180) + d2fsin_d(y * 360)) / 2)
  636. typedef struct ht_function_s {
  637. const char *fname;
  638. floatp (*proc)(floatp, floatp);
  639. } ht_function_t;
  640. private const ht_function_t ht_functions[] = {
  641. {"Round", ht_Round},
  642. {"Diamond", ht_Diamond},
  643. {"Ellipse", ht_Ellipse},
  644. {"EllipseA", ht_EllipseA},
  645. {"InvertedEllipseA", ht_InvertedEllipseA},
  646. {"EllipseB", ht_EllipseB},
  647. {"EllipseC", ht_EllipseC},
  648. {"InvertedEllipseC", ht_InvertedEllipseC},
  649. {"Line", ht_Line},
  650. {"LineX", ht_LineX},
  651. {"LineY", ht_LineY},
  652. {"Square", ht_Square},
  653. {"Cross", ht_Cross},
  654. {"Rhomboid", ht_Rhomboid},
  655. {"DoubleDot", ht_DoubleDot},
  656. {"InvertedDoubleDot", ht_InvertedDoubleDot},
  657. {"SimpleDot", ht_SimpleDot},
  658. {"InvertedSimpleDot", ht_InvertedSimpleDot},
  659. {"CosineDot", ht_CosineDot},
  660. {"Double", ht_Double},
  661. {"InvertedDouble", ht_InvertedDouble}
  662. };
  663. /* Write each kind of halftone. */
  664. private int
  665. pdf_write_spot_function(gx_device_pdf *pdev, const gx_ht_order *porder,
  666. long *pid)
  667. {
  668. /****** DOESN'T HANDLE STRIP HALFTONES ******/
  669. int w = porder->width, h = porder->height;
  670. uint num_bits = porder->num_bits;
  671. gs_function_Sd_params_t params;
  672. static const float domain_spot[4] = { -1, 1, -1, 1 };
  673. static const float range_spot[4] = { -1, 1 };
  674. int size[2];
  675. gs_memory_t *mem = pdev->pdf_memory;
  676. /*
  677. * Even though the values are logically ushort, we must always store
  678. * them in big-endian order, so we access them as bytes.
  679. */
  680. byte *values;
  681. gs_function_t *pfn;
  682. uint i;
  683. int code = 0;
  684. params.m = 2;
  685. params.Domain = domain_spot;
  686. params.n = 1;
  687. params.Range = range_spot;
  688. params.Order = 0; /* default */
  689. /*
  690. * We could use 8, 16, or 32 bits per sample to save space, but for
  691. * simplicity, we always use 16.
  692. */
  693. if (num_bits > 0x10000)
  694. return_error(gs_error_rangecheck);
  695. params.BitsPerSample = 16;
  696. params.Encode = 0;
  697. /*
  698. * The default Decode array maps the actual data values [1 .. w*h] to a
  699. * sub-interval of the Range, but that's OK, since all that matters is
  700. * the relative values, not the absolute values.
  701. */
  702. params.Decode = 0;
  703. size[0] = w;
  704. size[1] = h;
  705. params.Size = size;
  706. /* Create the (temporary) threshold array. */
  707. values = gs_alloc_byte_array(mem, num_bits, 2, "pdf_write_spot_function");
  708. if (values == 0)
  709. return_error(gs_error_VMerror);
  710. for (i = 0; i < num_bits; ++i) {
  711. gs_int_point pt;
  712. int value;
  713. if ((code = porder->procs->bit_index(porder, i, &pt)) < 0)
  714. break;
  715. value = pt.y * w + pt.x;
  716. /* Always store the values in big-endian order. */
  717. values[i * 2] = (byte)(value >> 8);
  718. values[i * 2 + 1] = (byte)value;
  719. }
  720. data_source_init_bytes(&params.DataSource, (const byte *)values,
  721. sizeof(*values) * num_bits);
  722. if (code >= 0 &&
  723. (code = gs_function_Sd_init(&pfn, &params, mem)) >= 0
  724. ) {
  725. code = pdf_write_function(pdev, pfn, pid);
  726. gs_function_free(pfn, false, mem);
  727. }
  728. gs_free_object(mem, values, "pdf_write_spot_function");
  729. return code;
  730. }
  731. private int
  732. pdf_write_spot_halftone(gx_device_pdf *pdev, const gs_spot_halftone *psht,
  733. const gx_ht_order *porder, long *pid)
  734. {
  735. char trs[17 + MAX_FN_CHARS + 1];
  736. int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
  737. trs);
  738. long id, spot_id;
  739. stream *s;
  740. int i = countof(ht_functions);
  741. gs_memory_t *mem = pdev->pdf_memory;
  742. if (code < 0)
  743. return code;
  744. /*
  745. * See if we can recognize the spot function, by comparing its sampled
  746. * values against those in the order.
  747. */
  748. { gs_screen_enum senum;
  749. gx_ht_order order;
  750. int code;
  751. order = *porder;
  752. code = gs_screen_order_alloc(&order, mem);
  753. if (code < 0)
  754. goto notrec;
  755. for (i = 0; i < countof(ht_functions); ++i) {
  756. floatp (*spot_proc)(floatp, floatp) = ht_functions[i].proc;
  757. gs_point pt;
  758. gs_screen_enum_init_memory(&senum, &order, NULL, &psht->screen,
  759. mem);
  760. while ((code = gs_screen_currentpoint(&senum, &pt)) == 0 &&
  761. gs_screen_next(&senum, spot_proc(pt.x, pt.y)) >= 0)
  762. DO_NOTHING;
  763. if (code < 0)
  764. continue;
  765. /* Compare the bits and levels arrays. */
  766. if (memcmp(order.levels, porder->levels,
  767. order.num_levels * sizeof(*order.levels)))
  768. continue;
  769. if (memcmp(order.bit_data, porder->bit_data,
  770. order.num_bits * porder->procs->bit_data_elt_size))
  771. continue;
  772. /* We have a match. */
  773. break;
  774. }
  775. gx_ht_order_release(&order, mem, false);
  776. }
  777. notrec:
  778. if (i == countof(ht_functions)) {
  779. /* Create and write a Function for the spot function. */
  780. pdf_write_spot_function(pdev, porder, &spot_id);
  781. }
  782. *pid = id = pdf_begin_separate(pdev);
  783. s = pdev->strm;
  784. /* Use the original, requested frequency and angle. */
  785. pprintg2(s, "<</Type/Halftone/HalftoneType 1/Frequency %g/Angle %g",
  786. psht->screen.frequency, psht->screen.angle);
  787. if (i < countof(ht_functions))
  788. pprints1(s, "/SpotFunction/%s", ht_functions[i].fname);
  789. else
  790. pprintld1(s, "/SpotFunction %ld 0 R", spot_id);
  791. stream_puts(s, trs);
  792. if (psht->accurate_screens)
  793. stream_puts(s, "/AccurateScreens true");
  794. stream_puts(s, ">>\n");
  795. return pdf_end_separate(pdev);
  796. }
  797. private int
  798. pdf_write_screen_halftone(gx_device_pdf *pdev, const gs_screen_halftone *psht,
  799. const gx_ht_order *porder, long *pid)
  800. {
  801. gs_spot_halftone spot;
  802. spot.screen = *psht;
  803. spot.accurate_screens = false;
  804. spot.transfer = 0;
  805. spot.transfer_closure.proc = 0;
  806. return pdf_write_spot_halftone(pdev, &spot, porder, pid);
  807. }
  808. private int
  809. pdf_write_colorscreen_halftone(gx_device_pdf *pdev,
  810. const gs_colorscreen_halftone *pcsht,
  811. const gx_device_halftone *pdht, long *pid)
  812. {
  813. int i;
  814. stream *s;
  815. long ht_ids[4];
  816. for (i = 0; i < pdht->num_comp ; ++i) {
  817. int code = pdf_write_screen_halftone(pdev, &pcsht->screens.indexed[i],
  818. &pdht->components[i].corder,
  819. &ht_ids[i]);
  820. if (code < 0)
  821. return code;
  822. }
  823. *pid = pdf_begin_separate(pdev);
  824. s = pdev->strm;
  825. /* Use Black, Gray as the Default unless we are in RGB colormodel */
  826. /* (num_comp < 4) in which case we use Green (arbitrarily) */
  827. pprintld1(s, "<</Type/Halftone/HalftoneType 5/Default %ld 0 R\n",
  828. pdht->num_comp > 3 ? ht_ids[3] : ht_ids[1]);
  829. pprintld2(s, "/Red %ld 0 R/Cyan %ld 0 R", ht_ids[0], ht_ids[0]);
  830. pprintld2(s, "/Green %ld 0 R/Magenta %ld 0 R", ht_ids[1], ht_ids[1]);
  831. pprintld2(s, "/Blue %ld 0 R/Yellow %ld 0 R", ht_ids[2], ht_ids[2]);
  832. if (pdht->num_comp > 3)
  833. pprintld2(s, "/Gray %ld 0 R/Black %ld 0 R", ht_ids[3], ht_ids[3]);
  834. stream_puts(s, ">>\n");
  835. return pdf_end_separate(pdev);
  836. }
  837. #define CHECK(expr)\
  838. BEGIN if ((code = (expr)) < 0) return code; END
  839. private int
  840. pdf_write_threshold_halftone(gx_device_pdf *pdev,
  841. const gs_threshold_halftone *ptht,
  842. const gx_ht_order *porder, long *pid)
  843. {
  844. char trs[17 + MAX_FN_CHARS + 1];
  845. stream *s;
  846. pdf_data_writer_t writer;
  847. int code = pdf_write_transfer(pdev, porder->transfer, "",
  848. trs);
  849. if (code < 0)
  850. return code;
  851. CHECK(pdf_begin_data(pdev, &writer));
  852. s = pdev->strm;
  853. *pid = writer.pres->object->id;
  854. CHECK(cos_dict_put_c_strings((cos_dict_t *)writer.pres->object,
  855. "/Type", "/Halftone"));
  856. CHECK(cos_dict_put_c_strings((cos_dict_t *)writer.pres->object,
  857. "/HalftoneType", "6"));
  858. CHECK(cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
  859. "/Width", ptht->width));
  860. CHECK(cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
  861. "/Height", ptht->height));
  862. if (*trs != 0)
  863. CHECK(cos_dict_put_c_strings((cos_dict_t *)writer.pres->object,
  864. "/TransferFunction", trs));
  865. stream_write(writer.binary.strm, ptht->thresholds.data, ptht->thresholds.size);
  866. return pdf_end_data(&writer);
  867. }
  868. private int
  869. pdf_write_threshold2_halftone(gx_device_pdf *pdev,
  870. const gs_threshold2_halftone *ptht,
  871. const gx_ht_order *porder, long *pid)
  872. {
  873. char trs[17 + MAX_FN_CHARS + 1];
  874. stream *s;
  875. pdf_data_writer_t writer;
  876. int code = pdf_write_transfer(pdev, porder->transfer, "/TransferFunction",
  877. trs);
  878. if (code < 0)
  879. return code;
  880. CHECK(pdf_begin_data(pdev, &writer));
  881. s = pdev->strm;
  882. *pid = writer.pres->object->id;
  883. CHECK(cos_dict_put_c_strings((cos_dict_t *)writer.pres->object,
  884. "/Type", "/Halftone"));
  885. CHECK(cos_dict_put_c_strings((cos_dict_t *)writer.pres->object,
  886. "/HalftoneType", "16"));
  887. CHECK(cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
  888. "/Width", ptht->width));
  889. CHECK(cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
  890. "/Height", ptht->height));
  891. if (ptht->width2 && ptht->height2) {
  892. CHECK(cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
  893. "/Width2", ptht->width2));
  894. CHECK(cos_dict_put_c_key_int((cos_dict_t *)writer.pres->object,
  895. "/Height2", ptht->height2));
  896. }
  897. if (*trs != 0)
  898. CHECK(cos_dict_put_c_strings((cos_dict_t *)writer.pres->object,
  899. "/TransferFunction", trs));
  900. s = writer.binary.strm;
  901. if (ptht->bytes_per_sample == 2)
  902. stream_write(s, ptht->thresholds.data, ptht->thresholds.size);
  903. else {
  904. /* Expand 1-byte to 2-byte samples. */
  905. int i;
  906. for (i = 0; i < ptht->thresholds.size; ++i) {
  907. byte b = ptht->thresholds.data[i];
  908. stream_putc(s, b);
  909. stream_putc(s, b);
  910. }
  911. }
  912. return pdf_end_data(&writer);
  913. }
  914. private int
  915. pdf_get_halftone_component_index(const gs_multiple_halftone *pmht,
  916. const gx_device_halftone *pdht,
  917. int dht_index)
  918. {
  919. int j;
  920. for (j = 0; j < pmht->num_comp; j++)
  921. if (pmht->components[j].comp_number == dht_index)
  922. break;
  923. if (j == pmht->num_comp) {
  924. /* Look for Default. */
  925. for (j = 0; j < pmht->num_comp; j++)
  926. if (pmht->components[j].comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS)
  927. break;
  928. if (j == pmht->num_comp)
  929. return_error(gs_error_undefined);
  930. }
  931. return j;
  932. }
  933. private int
  934. pdf_write_multiple_halftone(gx_device_pdf *pdev,
  935. const gs_multiple_halftone *pmht,
  936. const gx_device_halftone *pdht, long *pid)
  937. {
  938. stream *s;
  939. int i, code, last_comp = 0;
  940. gs_memory_t *mem = pdev->pdf_memory;
  941. long *ids;
  942. bool done_Default = false;
  943. ids = (long *)gs_alloc_byte_array(mem, pmht->num_comp, sizeof(long),
  944. "pdf_write_multiple_halftone");
  945. if (ids == 0)
  946. return_error(gs_error_VMerror);
  947. for (i = 0; i < pdht->num_comp; ++i) {
  948. const gs_halftone_component *phtc;
  949. const gx_ht_order *porder;
  950. code = pdf_get_halftone_component_index(pmht, pdht, i);
  951. if (code < 0)
  952. return code;
  953. if (pmht->components[code].comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
  954. if (done_Default)
  955. continue;
  956. done_Default = true;
  957. }
  958. phtc = &pmht->components[code];
  959. porder = (pdht->components == 0 ? &pdht->order :
  960. &pdht->components[i].corder);
  961. switch (phtc->type) {
  962. case ht_type_spot:
  963. code = pdf_write_spot_halftone(pdev, &phtc->params.spot,
  964. porder, &ids[i]);
  965. break;
  966. case ht_type_threshold:
  967. code = pdf_write_threshold_halftone(pdev, &phtc->params.threshold,
  968. porder, &ids[i]);
  969. break;
  970. case ht_type_threshold2:
  971. code = pdf_write_threshold2_halftone(pdev,
  972. &phtc->params.threshold2,
  973. porder, &ids[i]);
  974. break;
  975. default:
  976. code = gs_note_error(gs_error_rangecheck);
  977. }
  978. if (code < 0) {
  979. gs_free_object(mem, ids, "pdf_write_multiple_halftone");
  980. return code;
  981. }
  982. }
  983. *pid = pdf_begin_separate(pdev);
  984. s = pdev->strm;
  985. stream_puts(s, "<</Type/Halftone/HalftoneType 5\n");
  986. done_Default = false;
  987. for (i = 0; i < pdht->num_comp; ++i) {
  988. const gs_halftone_component *phtc;
  989. byte *str;
  990. uint len;
  991. cos_value_t value;
  992. code = pdf_get_halftone_component_index(pmht, pdht, i);
  993. if (code < 0)
  994. return code;
  995. if (pmht->components[code].comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
  996. if (done_Default)
  997. continue;
  998. done_Default = true;
  999. }
  1000. phtc = &pmht->components[code];
  1001. if ((code = pmht->get_colorname_string(pdev->memory, phtc->cname, &str, &len)) < 0 ||
  1002. (code = pdf_string_to_cos_name(pdev, str, len, &value)) < 0)
  1003. return code;
  1004. cos_value_write(&value, pdev);
  1005. gs_free_string(mem, value.contents.chars.data,
  1006. value.contents.chars.size,
  1007. "pdf_write_multiple_halftone");
  1008. pprintld1(s, " %ld 0 R\n", ids[i]);
  1009. last_comp = i;
  1010. }
  1011. if (!done_Default) {
  1012. /*
  1013. * BOGUS: Type 5 halftones must contain Default component.
  1014. * Perhaps we have no way to obtain it,
  1015. * because pdht contains ProcessColorModel components only.
  1016. * We copy the last component as Default one.
  1017. */
  1018. pprintld1(s, " /Default %ld 0 R\n", ids[last_comp]);
  1019. }
  1020. stream_puts(s, ">>\n");
  1021. gs_free_object(mem, ids, "pdf_write_multiple_halftone");
  1022. return pdf_end_separate(pdev);
  1023. }
  1024. /*
  1025. * Update the halftone. This is a separate procedure only for
  1026. * readability.
  1027. */
  1028. private int
  1029. pdf_update_halftone(gx_device_pdf *pdev, const gs_imager_state *pis,
  1030. char *hts)
  1031. {
  1032. const gs_halftone *pht = pis->halftone;
  1033. const gx_device_halftone *pdht = pis->dev_ht;
  1034. int code;
  1035. long id;
  1036. switch (pht->type) {
  1037. case ht_type_screen:
  1038. code = pdf_write_screen_halftone(pdev, &pht->params.screen,
  1039. &pdht->components[0].corder, &id);
  1040. break;
  1041. case ht_type_colorscreen:
  1042. code = pdf_write_colorscreen_halftone(pdev, &pht->params.colorscreen,
  1043. pdht, &id);
  1044. break;
  1045. case ht_type_spot:
  1046. code = pdf_write_spot_halftone(pdev, &pht->params.spot,
  1047. &pdht->components[0].corder, &id);
  1048. break;
  1049. case ht_type_threshold:
  1050. code = pdf_write_threshold_halftone(pdev, &pht->params.threshold,
  1051. &pdht->components[0].corder, &id);
  1052. break;
  1053. case ht_type_threshold2:
  1054. code = pdf_write_threshold2_halftone(pdev, &pht->params.threshold2,
  1055. &pdht->components[0].corder, &id);
  1056. break;
  1057. case ht_type_multiple:
  1058. case ht_type_multiple_colorscreen:
  1059. code = pdf_write_multiple_halftone(pdev, &pht->params.multiple,
  1060. pdht, &id);
  1061. break;
  1062. default:
  1063. return_error(gs_error_rangecheck);
  1064. }
  1065. if (code < 0)
  1066. return code;
  1067. sprintf(hts, "%ld 0 R", id);
  1068. pdev->halftone_id = pis->dev_ht->id;
  1069. return code;
  1070. }
  1071. /* ------ Graphics state updating ------ */
  1072. private inline cos_dict_t *
  1073. resource_dict(pdf_resource_t *pres)
  1074. {
  1075. return (cos_dict_t *)pres->object;
  1076. }
  1077. /* Open an ExtGState. */
  1078. private int
  1079. pdf_open_gstate(gx_device_pdf *pdev, pdf_resource_t **ppres)
  1080. {
  1081. int code;
  1082. if (*ppres)
  1083. return 0;
  1084. /*
  1085. * We write gs command only in stream context.
  1086. * If we are clipped, and the clip path is about to change,
  1087. * the old clipping must be undone before writing gs.
  1088. */
  1089. if (pdev->context != PDF_IN_STREAM) {
  1090. /* We apparently use gs_error_interrupt as a request to change context. */
  1091. return gs_error_interrupt;
  1092. }
  1093. code = pdf_alloc_resource(pdev, resourceExtGState, gs_no_id, ppres, -1L);
  1094. if (code < 0)
  1095. return code;
  1096. cos_become((*ppres)->object, cos_type_dict);
  1097. code = cos_dict_put_c_key_string(resource_dict(*ppres), "/Type", (const byte *)"/ExtGState", 10);
  1098. if (code < 0)
  1099. return code;
  1100. return 0;
  1101. }
  1102. /* Finish writing an ExtGState. */
  1103. int
  1104. pdf_end_gstate(gx_device_pdf *pdev, pdf_resource_t *pres)
  1105. {
  1106. if (pres) {
  1107. int code = pdf_substitute_resource(pdev, &pres, resourceExtGState, NULL, true);
  1108. if (code < 0)
  1109. return code;
  1110. code = pdf_open_page(pdev, PDF_IN_STREAM);
  1111. if (code < 0)
  1112. return code;
  1113. code = pdf_add_resource(pdev, pdev->substream_Resources, "/ExtGState", pres);
  1114. if (code < 0)
  1115. return code;
  1116. pprintld1(pdev->strm, "/R%ld gs\n", pdf_resource_id(pres));
  1117. pres->where_used |= pdev->used_mask;
  1118. }
  1119. return 0;
  1120. }
  1121. /*
  1122. * Update the transfer functions(s). This is a separate procedure only
  1123. * for readability.
  1124. */
  1125. private int
  1126. pdf_update_transfer(gx_device_pdf *pdev, const gs_imager_state *pis,
  1127. char *trs)
  1128. {
  1129. int i, pi = -1;
  1130. bool multiple = false, update = false;
  1131. gs_id transfer_ids[4];
  1132. int code = 0;
  1133. const gx_transfer_map *tm[4];
  1134. tm[0] = pis->set_transfer.red;
  1135. tm[1] = pis->set_transfer.green;
  1136. tm[2] = pis->set_transfer.blue;
  1137. tm[3] = pis->set_transfer.gray;
  1138. for (i = 0; i < 4; ++i)
  1139. if (tm[i] != NULL) {
  1140. transfer_ids[i] = tm[i]->id;
  1141. if (pdev->transfer_ids[i] != tm[i]->id)
  1142. update = true;
  1143. if (pi != -1 && transfer_ids[i] != transfer_ids[pi])
  1144. multiple = true;
  1145. pi = i;
  1146. } else
  1147. transfer_ids[i] = -1;
  1148. if (update) {
  1149. int mask;
  1150. if (!multiple) {
  1151. code = pdf_write_transfer(pdev, tm[pi], "", trs);
  1152. if (code < 0)
  1153. return code;
  1154. mask = code == 0;
  1155. } else {
  1156. strcpy(trs, "[");
  1157. mask = 0;
  1158. for (i = 0; i < 4; ++i)
  1159. if (tm[i] != NULL) {
  1160. code = pdf_write_transfer_map(pdev,
  1161. tm[i],
  1162. 0, true, " ", trs + strlen(trs));
  1163. if (code < 0)
  1164. return code;
  1165. mask |= (code == 0) << i;
  1166. }
  1167. strcat(trs, "]");
  1168. }
  1169. memcpy(pdev->transfer_ids, transfer_ids, sizeof(pdev->transfer_ids));
  1170. pdev->transfer_not_identity = mask;
  1171. }
  1172. return code;
  1173. }
  1174. /*
  1175. * Update the current alpha if necessary. Note that because Ghostscript
  1176. * stores separate opacity and shape alpha, a rangecheck will occur if
  1177. * both are different from the current setting.
  1178. */
  1179. private int
  1180. pdf_update_alpha(gx_device_pdf *pdev, const gs_imager_state *pis,
  1181. pdf_resource_t **ppres)
  1182. {
  1183. bool ais;
  1184. floatp alpha;
  1185. int code;
  1186. if (pdev->state.soft_mask_id != pis->soft_mask_id) {
  1187. char buf[20];
  1188. sprintf(buf, "%ld 0 R", pis->soft_mask_id);
  1189. code = pdf_open_gstate(pdev, ppres);
  1190. if (code < 0)
  1191. return code;
  1192. code = cos_dict_put_c_key_string(resource_dict(*ppres),
  1193. "/SMask", (byte *)buf, strlen(buf));
  1194. if (code < 0)
  1195. return code;
  1196. pdev->state.soft_mask_id = pis->soft_mask_id;
  1197. }
  1198. if (pdev->state.opacity.alpha != pis->opacity.alpha) {
  1199. if (pdev->state.shape.alpha != pis->shape.alpha)
  1200. return_error(gs_error_rangecheck);
  1201. ais = false;
  1202. alpha = pdev->state.opacity.alpha = pis->opacity.alpha;
  1203. } else if (pdev->state.shape.alpha != pis->shape.alpha) {
  1204. ais = true;
  1205. alpha = pdev->state.shape.alpha = pis->shape.alpha;
  1206. } else
  1207. return 0;
  1208. code = pdf_open_gstate(pdev, ppres);
  1209. if (code < 0)
  1210. return code;
  1211. code = cos_dict_put_c_key_bool(resource_dict(*ppres), "/AIS", ais);
  1212. if (code < 0)
  1213. return code;
  1214. /* we never do the 'both' operations (b, B, b*, B*) so we set both */
  1215. /* CA and ca the same so that we stay in sync with state.*.alpha */
  1216. code = cos_dict_put_c_key_real(resource_dict(*ppres), "/CA", alpha);
  1217. if (code < 0)
  1218. return code;
  1219. return cos_dict_put_c_key_real(resource_dict(*ppres), "/ca", alpha);
  1220. }
  1221. /*
  1222. * Update the graphics subset common to all high-level drawing operations.
  1223. */
  1224. int
  1225. pdf_prepare_drawing(gx_device_pdf *pdev, const gs_imager_state *pis,
  1226. pdf_resource_t **ppres)
  1227. {
  1228. int code = 0;
  1229. int bottom;
  1230. if (pdev->CompatibilityLevel >= 1.4) {
  1231. if (pdev->state.blend_mode != pis->blend_mode) {
  1232. static const char *const bm_names[] = { GS_BLEND_MODE_NAMES };
  1233. char buf[20];
  1234. code = pdf_open_gstate(pdev, ppres);
  1235. if (code < 0)
  1236. return code;
  1237. buf[0] = '/';
  1238. strncpy(buf + 1, bm_names[pis->blend_mode], sizeof(buf) - 2);
  1239. code = cos_dict_put_string_copy(resource_dict(*ppres), "/BM", buf);
  1240. if (code < 0)
  1241. return code;
  1242. pdev->state.blend_mode = pis->blend_mode;
  1243. }
  1244. code = pdf_update_alpha(pdev, pis, ppres);
  1245. if (code < 0)
  1246. return code;
  1247. } else {
  1248. /*
  1249. * If the graphics state calls for any transparency functions,
  1250. * we can't represent them, so return a rangecheck.
  1251. */
  1252. if (pis->opacity.alpha != 1 || pis->opacity.mask != 0 ||
  1253. pis->shape.alpha != 1 || pis->shape.mask != 0 ||
  1254. pis->transparency_stack != 0
  1255. )
  1256. return_error(gs_error_rangecheck);
  1257. }
  1258. /*
  1259. * We originally thought the remaining items were only needed for
  1260. * fill and stroke, but in fact they are needed for images as well.
  1261. */
  1262. /*
  1263. * Update halftone, transfer function, black generation, undercolor
  1264. * removal, halftone phase, overprint mode, smoothness, blend mode, text
  1265. * knockout.
  1266. */
  1267. bottom = (pdev->ResourcesBeforeUsage ? 1 : 0);
  1268. /* When ResourcesBeforeUsage != 0, one sbstack element
  1269. appears from the page contents stream. */
  1270. if (pdev->sbstack_depth == bottom) {
  1271. gs_int_point phase, dev_phase;
  1272. char hts[5 + MAX_FN_CHARS + 1],
  1273. trs[5 + MAX_FN_CHARS * 4 + 6 + 1],
  1274. bgs[5 + MAX_FN_CHARS + 1],
  1275. ucrs[6 + MAX_FN_CHARS + 1];
  1276. hts[0] = trs[0] = bgs[0] = ucrs[0] = 0;
  1277. if (pdev->params.PreserveHalftoneInfo &&
  1278. pdev->halftone_id != pis->dev_ht->id &&
  1279. !pdev->PDFX
  1280. ) {
  1281. code = pdf_update_halftone(pdev, pis, hts);
  1282. if (code < 0)
  1283. return code;
  1284. }
  1285. if (pdev->params.TransferFunctionInfo == tfi_Preserve &&
  1286. !pdev->PDFX
  1287. ) {
  1288. code = pdf_update_transfer(pdev, pis, trs);
  1289. if (code < 0)
  1290. return code;
  1291. }
  1292. if (pdev->params.UCRandBGInfo == ucrbg_Preserve) {
  1293. if (pdev->black_generation_id != pis->black_generation->id) {
  1294. code = pdf_write_transfer_map(pdev, pis->black_generation,
  1295. 0, false, "", bgs);
  1296. if (code < 0)
  1297. return code;
  1298. pdev->black_generation_id = pis->black_generation->id;
  1299. }
  1300. if (pdev->undercolor_removal_id != pis->undercolor_removal->id) {
  1301. code = pdf_write_transfer_map(pdev, pis->undercolor_removal,
  1302. -1, false, "", ucrs);
  1303. if (code < 0)
  1304. return code;
  1305. pdev->undercolor_removal_id = pis->undercolor_removal->id;
  1306. }
  1307. }
  1308. if (hts[0] || trs[0] || bgs[0] || ucrs[0]) {
  1309. code = pdf_open_gstate(pdev, ppres);
  1310. if (code < 0)
  1311. return code;
  1312. }
  1313. if (hts[0]) {
  1314. code = cos_dict_put_string_copy(resource_dict(*ppres), "/HT", hts);
  1315. if (code < 0)
  1316. return code;
  1317. }
  1318. if (trs[0]) {
  1319. code = cos_dict_put_string_copy(resource_dict(*ppres), "/TR", trs);
  1320. if (code < 0)
  1321. return code;
  1322. }
  1323. if (bgs[0]) {
  1324. code = cos_dict_put_string_copy(resource_dict(*ppres), "/BG", bgs);
  1325. if (code < 0)
  1326. return code;
  1327. }
  1328. if (ucrs[0]) {
  1329. code = cos_dict_put_string_copy(resource_dict(*ppres), "/UCR", ucrs);
  1330. if (code < 0)
  1331. return code;
  1332. }
  1333. if (!pdev->PDFX) {
  1334. gs_currentscreenphase_pis(pis, &phase, 0);
  1335. gs_currentscreenphase_pis(&pdev->state, &dev_phase, 0);
  1336. if (dev_phase.x != phase.x || dev_phase.y != phase.y) {
  1337. char buf[sizeof(int) * 3 + 5];
  1338. code = pdf_open_gstate(pdev, ppres);
  1339. if (code < 0)
  1340. return code;
  1341. sprintf(buf, "[%d %d]", phase.x, phase.y);
  1342. code = cos_dict_put_string_copy(resource_dict(*ppres), "/HTP", buf);
  1343. if (code < 0)
  1344. return code;
  1345. gx_imager_setscreenphase(&pdev->state, phase.x, phase.y,
  1346. gs_color_select_all);
  1347. }
  1348. }
  1349. }
  1350. if (pdev->CompatibilityLevel >= 1.3 && pdev->sbstack_depth == bottom) {
  1351. if (pdev->overprint_mode != pdev->params.OPM) {
  1352. code = pdf_open_gstate(pdev, ppres);
  1353. if (code < 0)
  1354. return code;
  1355. code = cos_dict_put_c_key_int(resource_dict(*ppres), "/OPM", pdev->params.OPM);
  1356. if (code < 0)
  1357. return code;
  1358. pdev->overprint_mode = pdev->params.OPM;
  1359. }
  1360. if (pdev->state.smoothness != pis->smoothness) {
  1361. code = pdf_open_gstate(pdev, ppres);
  1362. if (code < 0)
  1363. return code;
  1364. code = cos_dict_put_c_key_real(resource_dict(*ppres), "/SM", pis->smoothness);
  1365. if (code < 0)
  1366. return code;
  1367. pdev->state.smoothness = pis->smoothness;
  1368. }
  1369. if (pdev->CompatibilityLevel >= 1.4) {
  1370. if (pdev->state.text_knockout != pis->text_knockout) {
  1371. code = pdf_open_gstate(pdev, ppres);
  1372. if (code < 0)
  1373. return code;
  1374. code = cos_dict_put_c_key_bool(resource_dict(*ppres), "/TK", pis->text_knockout);
  1375. if (code < 0)
  1376. return code;
  1377. pdev->state.text_knockout = pis->text_knockout;
  1378. }
  1379. }
  1380. }
  1381. return code;
  1382. }
  1383. /* Update the graphics state for filling. */
  1384. int
  1385. pdf_try_prepare_fill(gx_device_pdf *pdev, const gs_imager_state *pis)
  1386. {
  1387. pdf_resource_t *pres = 0;
  1388. int code = pdf_prepare_drawing(pdev, pis, &pres);
  1389. if (code < 0)
  1390. return code;
  1391. /* Update overprint. */
  1392. if (pdev->params.PreserveOverprintSettings &&
  1393. pdev->fill_overprint != pis->overprint &&
  1394. !pdev->skip_colors
  1395. ) {
  1396. code = pdf_open_gstate(pdev, &pres);
  1397. if (code < 0)
  1398. return code;
  1399. /* PDF 1.2 only has a single overprint setting. */
  1400. if (pdev->CompatibilityLevel < 1.3) {
  1401. code = cos_dict_put_c_key_bool(resource_dict(pres), "/OP", pis->overprint);
  1402. if (code < 0)
  1403. return code;
  1404. pdev->stroke_overprint = pis->overprint;
  1405. } else {
  1406. code = cos_dict_put_c_key_bool(resource_dict(pres), "/op", pis->overprint);
  1407. if (code < 0)
  1408. return code;
  1409. }
  1410. pdev->fill_overprint = pis->overprint;
  1411. }
  1412. return pdf_end_gstate(pdev, pres);
  1413. }
  1414. int
  1415. pdf_prepare_fill(gx_device_pdf *pdev, const gs_imager_state *pis)
  1416. {
  1417. int code;
  1418. if (pdev->context != PDF_IN_STREAM) {
  1419. code = pdf_try_prepare_fill(pdev, pis);
  1420. if (code != gs_error_interrupt) /* See pdf_open_gstate */
  1421. return code;
  1422. code = pdf_open_contents(pdev, PDF_IN_STREAM);
  1423. if (code < 0)
  1424. return code;
  1425. }
  1426. return pdf_try_prepare_fill(pdev, pis);
  1427. }
  1428. /* Update the graphics state for stroking. */
  1429. private int
  1430. pdf_try_prepare_stroke(gx_device_pdf *pdev, const gs_imager_state *pis)
  1431. {
  1432. pdf_resource_t *pres = 0;
  1433. int code = pdf_prepare_drawing(pdev, pis, &pres);
  1434. if (code < 0)
  1435. return code;
  1436. /* Update overprint, stroke adjustment. */
  1437. if (pdev->params.PreserveOverprintSettings &&
  1438. pdev->stroke_overprint != pis->overprint &&
  1439. !pdev->skip_colors
  1440. ) {
  1441. code = pdf_open_gstate(pdev, &pres);
  1442. if (code < 0)
  1443. return code;
  1444. code = cos_dict_put_c_key_bool(resource_dict(pres), "/OP", pis->overprint);
  1445. if (code < 0)
  1446. return code;
  1447. pdev->stroke_overprint = pis->overprint;
  1448. if (pdev->CompatibilityLevel < 1.3) {
  1449. /* PDF 1.2 only has a single overprint setting. */
  1450. pdev->fill_overprint = pis->overprint;
  1451. } else {
  1452. /* According to PDF>=1.3 spec, OP also sets op,
  1453. if there is no /op in same garphic state object.
  1454. We don't write /op, so monitor the viewer's state here : */
  1455. pdev->fill_overprint = pis->overprint;
  1456. }
  1457. }
  1458. if (pdev->state.stroke_adjust != pis->stroke_adjust) {
  1459. code = pdf_open_gstate(pdev, &pres);
  1460. if (code < 0)
  1461. return code;
  1462. code = cos_dict_put_c_key_bool(resource_dict(pres), "/SA", pis->stroke_adjust);
  1463. if (code < 0)
  1464. return code;
  1465. pdev->state.stroke_adjust = pis->stroke_adjust;
  1466. }
  1467. return pdf_end_gstate(pdev, pres);
  1468. }
  1469. int
  1470. pdf_prepare_stroke(gx_device_pdf *pdev, const gs_imager_state *pis)
  1471. {
  1472. int code;
  1473. if (pdev->context != PDF_IN_STREAM) {
  1474. code = pdf_try_prepare_stroke(pdev, pis);
  1475. if (code != gs_error_interrupt) /* See pdf_open_gstate */
  1476. return code;
  1477. code = pdf_open_contents(pdev, PDF_IN_STREAM);
  1478. if (code < 0)
  1479. return code;
  1480. }
  1481. return pdf_try_prepare_stroke(pdev, pis);
  1482. }
  1483. /* Update the graphics state for an image other than an ImageType 1 mask. */
  1484. int
  1485. pdf_prepare_image(gx_device_pdf *pdev, const gs_imager_state *pis)
  1486. {
  1487. /*
  1488. * As it turns out, this requires updating the same parameters as for
  1489. * filling.
  1490. */
  1491. return pdf_prepare_fill(pdev, pis);
  1492. }
  1493. /* Update the graphics state for an ImageType 1 mask. */
  1494. int
  1495. pdf_prepare_imagemask(gx_device_pdf *pdev, const gs_imager_state *pis,
  1496. const gx_drawing_color *pdcolor)
  1497. {
  1498. int code = pdf_prepare_image(pdev, pis);
  1499. if (code < 0)
  1500. return code;
  1501. return pdf_set_drawing_color(pdev, pis, pdcolor, &pdev->saved_fill_color,
  1502. &pdev->fill_used_process_color,
  1503. &psdf_set_fill_color_commands);
  1504. }