gdevp14.c 90 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910
  1. /*
  2. Copyright (C) 2001-2004 artofcode LLC.
  3. This software is provided AS-IS with no warranty, either express or
  4. implied.
  5. This software is distributed under license and may not be copied,
  6. modified or distributed except as expressly authorized under the terms
  7. of the license contained in the file LICENSE in this distribution.
  8. For more information about licensing, please refer to
  9. http://www.ghostscript.com/licensing/. For information on
  10. commercial licensing, go to http://www.artifex.com/licensing/ or
  11. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  12. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  13. Author: Raph Levien <raph@artofcode.com>
  14. */
  15. /* $Id: gdevp14.c,v 1.35 2005/10/10 18:58:18 leonardo Exp $ */
  16. /* Compositing devices for implementing PDF 1.4 imaging model */
  17. #include "math_.h"
  18. #include "memory_.h"
  19. #include "gx.h"
  20. #include "gserrors.h"
  21. #include "gscdefs.h"
  22. #include "gxdevice.h"
  23. #include "gsdevice.h"
  24. #include "gsstruct.h"
  25. #include "gxistate.h"
  26. #include "gxdcolor.h"
  27. #include "gxiparam.h"
  28. #include "gstparam.h"
  29. #include "gxblend.h"
  30. #include "gxtext.h"
  31. #include "gsdfilt.h"
  32. #include "gsimage.h"
  33. #include "gsrect.h"
  34. #include "gzstate.h"
  35. #include "gdevp14.h"
  36. #include "gsovrc.h"
  37. #include "gxcmap.h"
  38. #include "gscolor1.h"
  39. #include "gstrans.h"
  40. #include "gsutil.h"
  41. #include "gxcldev.h"
  42. /* #define DUMP_TO_PNG */
  43. #ifdef DUMP_TO_PNG
  44. #include "png_.h"
  45. #endif
  46. # define INCR(v) DO_NOTHING
  47. /* Buffer stack data structure */
  48. #define PDF14_MAX_PLANES 16
  49. /* GC procedures for buffer stack */
  50. private
  51. ENUM_PTRS_WITH(pdf14_buf_enum_ptrs, pdf14_buf *buf)
  52. return 0;
  53. case 0: return ENUM_OBJ(buf->saved);
  54. case 1: return ENUM_OBJ(buf->data);
  55. case 2: return ENUM_OBJ(buf->transfer_fn);
  56. ENUM_PTRS_END
  57. private
  58. RELOC_PTRS_WITH(pdf14_buf_reloc_ptrs, pdf14_buf *buf)
  59. {
  60. RELOC_VAR(buf->saved);
  61. RELOC_VAR(buf->data);
  62. RELOC_VAR(buf->transfer_fn);
  63. }
  64. RELOC_PTRS_END
  65. gs_private_st_composite(st_pdf14_buf, pdf14_buf, "pdf14_buf",
  66. pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs);
  67. gs_private_st_ptrs2(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
  68. pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
  69. stack, maskbuf);
  70. /* ------ The device descriptors ------ */
  71. /*
  72. * Default X and Y resolution.
  73. */
  74. #define X_DPI 72
  75. #define Y_DPI 72
  76. private int pdf14_open(gx_device * pdev);
  77. private dev_proc_close_device(pdf14_close);
  78. private int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
  79. private dev_proc_put_params(pdf14_put_params);
  80. private dev_proc_encode_color(pdf14_encode_color);
  81. private dev_proc_decode_color(pdf14_decode_color);
  82. private dev_proc_fill_rectangle(pdf14_fill_rectangle);
  83. private dev_proc_fill_rectangle(pdf14_mark_fill_rectangle);
  84. private dev_proc_fill_rectangle(pdf14_mark_fill_rectangle_ko_simple);
  85. private dev_proc_fill_path(pdf14_fill_path);
  86. private dev_proc_stroke_path(pdf14_stroke_path);
  87. private dev_proc_begin_typed_image(pdf14_begin_typed_image);
  88. private dev_proc_text_begin(pdf14_text_begin);
  89. private dev_proc_create_compositor(pdf14_create_compositor);
  90. private dev_proc_create_compositor(pdf14_forward_create_compositor);
  91. private dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
  92. private dev_proc_end_transparency_group(pdf14_end_transparency_group);
  93. private dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
  94. private dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
  95. private const gx_color_map_procs *
  96. pdf14_get_cmap_procs(const gs_imager_state *, const gx_device *);
  97. #define XSIZE (int)(8.5 * X_DPI) /* 8.5 x 11 inch page, by default */
  98. #define YSIZE (int)(11 * Y_DPI)
  99. /* 24-bit color. */
  100. #define pdf14_procs(get_color_mapping_procs, get_color_comp_index) \
  101. {\
  102. pdf14_open, /* open */\
  103. NULL, /* get_initial_matrix */\
  104. NULL, /* sync_output */\
  105. pdf14_output_page, /* output_page */\
  106. pdf14_close, /* close */\
  107. pdf14_encode_color, /* rgb_map_rgb_color */\
  108. pdf14_decode_color, /* gx_default_rgb_map_color_rgb */\
  109. pdf14_fill_rectangle, /* fill_rectangle */\
  110. NULL, /* tile_rectangle */\
  111. NULL, /* copy_mono */\
  112. NULL, /* copy_color */\
  113. NULL, /* draw_line */\
  114. NULL, /* get_bits */\
  115. NULL, /* get_params */\
  116. pdf14_put_params, /* put_params */\
  117. NULL, /* map_cmyk_color */\
  118. NULL, /* get_xfont_procs */\
  119. NULL, /* get_xfont_device */\
  120. NULL, /* map_rgb_alpha_color */\
  121. NULL, /* get_page_device */\
  122. NULL, /* get_alpha_bits */\
  123. NULL, /* copy_alpha */\
  124. NULL, /* get_band */\
  125. NULL, /* copy_rop */\
  126. pdf14_fill_path, /* fill_path */\
  127. pdf14_stroke_path, /* stroke_path */\
  128. NULL, /* fill_mask */\
  129. NULL, /* fill_trapezoid */\
  130. NULL, /* fill_parallelogram */\
  131. NULL, /* fill_triangle */\
  132. NULL, /* draw_thin_line */\
  133. NULL, /* begin_image */\
  134. NULL, /* image_data */\
  135. NULL, /* end_image */\
  136. NULL, /* strip_tile_rectangle */\
  137. NULL, /* strip_copy_rop, */\
  138. NULL, /* get_clipping_box */\
  139. pdf14_begin_typed_image, /* begin_typed_image */\
  140. NULL, /* get_bits_rectangle */\
  141. NULL, /* map_color_rgb_alpha */\
  142. pdf14_create_compositor, /* create_compositor */\
  143. NULL, /* get_hardware_params */\
  144. pdf14_text_begin, /* text_begin */\
  145. NULL, /* finish_copydevice */\
  146. pdf14_begin_transparency_group,\
  147. pdf14_end_transparency_group,\
  148. pdf14_begin_transparency_mask,\
  149. pdf14_end_transparency_mask,\
  150. NULL, /* discard_transparency_layer */\
  151. get_color_mapping_procs, /* get_color_mapping_procs */\
  152. get_color_comp_index, /* get_color_comp_index */\
  153. pdf14_encode_color, /* encode_color */\
  154. pdf14_decode_color /* decode_color */\
  155. }
  156. private const gx_device_procs pdf14_Gray_procs =
  157. pdf14_procs(gx_default_DevGray_get_color_mapping_procs,
  158. gx_default_DevGray_get_color_comp_index);
  159. private const gx_device_procs pdf14_RGB_procs =
  160. pdf14_procs(gx_default_DevRGB_get_color_mapping_procs,
  161. gx_default_DevRGB_get_color_comp_index);
  162. private const gx_device_procs pdf14_CMYK_procs =
  163. pdf14_procs(gx_default_DevCMYK_get_color_mapping_procs,
  164. gx_default_DevCMYK_get_color_comp_index);
  165. gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
  166. pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
  167. gx_device_finalize);
  168. const pdf14_device gs_pdf14_Gray_device = {
  169. std_device_color_stype_body(pdf14_device, &pdf14_Gray_procs, "pdf14gray",
  170. &st_pdf14_device,
  171. XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
  172. { 0 }
  173. };
  174. const pdf14_device gs_pdf14_RGB_device = {
  175. std_device_color_stype_body(pdf14_device, &pdf14_RGB_procs, "pdf14RGB",
  176. &st_pdf14_device,
  177. XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
  178. { 0 }
  179. };
  180. const pdf14_device gs_pdf14_CMYK_device = {
  181. std_device_std_color_full_body_type(pdf14_device, &pdf14_CMYK_procs,
  182. "PDF14cmyk", &st_pdf14_device, XSIZE, YSIZE, X_DPI, Y_DPI, 32,
  183. 0, 0, 0, 0, 0, 0),
  184. { 0 }
  185. };
  186. /* GC procedures */
  187. private
  188. ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev) return 0;
  189. case 0: return ENUM_OBJ(pdev->ctx);
  190. case 1: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
  191. ENUM_PTRS_END
  192. private RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
  193. {
  194. RELOC_VAR(pdev->ctx);
  195. pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
  196. }
  197. RELOC_PTRS_END
  198. /* ------ Private definitions ------ */
  199. /**
  200. * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
  201. * @n_chan: Number of pixel channels including alpha.
  202. *
  203. * Return value: Newly allocated buffer, or NULL on failure.
  204. **/
  205. private pdf14_buf *
  206. pdf14_buf_new(gs_int_rect *rect, bool has_alpha_g, bool has_shape,
  207. int n_chan,
  208. gs_memory_t *memory)
  209. {
  210. pdf14_buf *result;
  211. int rowstride = (rect->q.x - rect->p.x + 3) & -4;
  212. int height = (rect->q.y - rect->p.y);
  213. int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
  214. int planestride;
  215. double dsize = (((double) rowstride) * height) * n_planes;
  216. if (dsize > (double)max_uint)
  217. return NULL;
  218. result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
  219. "pdf14_buf_new");
  220. if (result == NULL)
  221. return result;
  222. result->isolated = false;
  223. result->knockout = false;
  224. result->has_alpha_g = has_alpha_g;
  225. result->has_shape = has_shape;
  226. result->rect = *rect;
  227. result->n_chan = n_chan;
  228. result->n_planes = n_planes;
  229. result->rowstride = rowstride;
  230. result->transfer_fn = NULL;
  231. if (height < 0) {
  232. /* Empty clipping - will skip all drawings. */
  233. result->planestride = 0;
  234. result->data = 0;
  235. } else {
  236. planestride = rowstride * height;
  237. result->planestride = planestride;
  238. result->data = gs_alloc_bytes(memory, planestride * n_planes,
  239. "pdf14_buf_new");
  240. if (result->data == NULL) {
  241. gs_free_object(memory, result, "pdf_buf_new");
  242. return NULL;
  243. }
  244. if (has_alpha_g) {
  245. int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
  246. memset (result->data + alpha_g_plane * planestride, 0, planestride);
  247. }
  248. }
  249. result->bbox.p.x = max_int;
  250. result->bbox.p.y = max_int;
  251. result->bbox.q.x = min_int;
  252. result->bbox.q.y = min_int;
  253. return result;
  254. }
  255. private void
  256. pdf14_buf_free(pdf14_buf *buf, gs_memory_t *memory)
  257. {
  258. gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
  259. gs_free_object(memory, buf->data, "pdf14_buf_free");
  260. gs_free_object(memory, buf, "pdf14_buf_free");
  261. }
  262. private pdf14_ctx *
  263. pdf14_ctx_new(gs_int_rect *rect, int n_chan, bool additive, gs_memory_t *memory)
  264. {
  265. pdf14_ctx *result;
  266. pdf14_buf *buf;
  267. result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx,
  268. "pdf14_ctx_new");
  269. if (result == NULL)
  270. return result;
  271. buf = pdf14_buf_new(rect, false, false, n_chan, memory);
  272. if (buf == NULL) {
  273. gs_free_object(memory, result, "pdf14_ctx_new");
  274. return NULL;
  275. }
  276. if_debug3('v', "[v]base buf: %d x %d, %d channels\n",
  277. buf->rect.q.x, buf->rect.q.y, buf->n_chan);
  278. memset(buf->data, 0, buf->planestride * buf->n_planes);
  279. buf->saved = NULL;
  280. result->stack = buf;
  281. result->maskbuf = NULL;
  282. result->n_chan = n_chan;
  283. result->memory = memory;
  284. result->rect = *rect;
  285. result->additive = additive;
  286. return result;
  287. }
  288. private void
  289. pdf14_ctx_free(pdf14_ctx *ctx)
  290. {
  291. pdf14_buf *buf, *next;
  292. for (buf = ctx->stack; buf != NULL; buf = next) {
  293. next = buf->saved;
  294. pdf14_buf_free(buf, ctx->memory);
  295. }
  296. gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
  297. }
  298. /**
  299. * pdf14_find_backdrop_buf: Find backdrop buffer.
  300. *
  301. * Return value: Backdrop buffer for current group operation, or NULL
  302. * if backdrop is fully transparent.
  303. **/
  304. private pdf14_buf *
  305. pdf14_find_backdrop_buf(pdf14_ctx *ctx)
  306. {
  307. pdf14_buf *buf = ctx->stack;
  308. while (buf != NULL) {
  309. if (buf->isolated) return NULL;
  310. if (!buf->knockout) return buf->saved;
  311. buf = buf->saved;
  312. }
  313. /* this really shouldn't happen, as bottom-most buf should be
  314. non-knockout */
  315. return NULL;
  316. }
  317. private int
  318. pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect,
  319. bool isolated, bool knockout,
  320. byte alpha, byte shape,
  321. gs_blend_mode_t blend_mode)
  322. {
  323. pdf14_buf *tos = ctx->stack;
  324. pdf14_buf *buf, *backdrop;
  325. bool has_shape;
  326. /* todo: fix this hack, which makes all knockout groups isolated.
  327. For the vast majority of files, there won't be any visible
  328. effects, but it still isn't correct. The pixel compositing code
  329. for non-isolated knockout groups gets pretty hairy, which is
  330. why this is here. */
  331. if (knockout)
  332. isolated = true;
  333. has_shape = tos->has_shape || tos->knockout;
  334. buf = pdf14_buf_new(rect, !isolated, has_shape, ctx->n_chan, ctx->memory);
  335. if_debug3('v', "[v]push buf: %d x %d, %d channels\n", buf->rect.p.x, buf->rect.p.y, buf->n_chan);
  336. if (buf == NULL)
  337. return_error(gs_error_VMerror);
  338. buf->isolated = isolated;
  339. buf->knockout = knockout;
  340. buf->alpha = alpha;
  341. buf->shape = shape;
  342. buf->blend_mode = blend_mode;
  343. buf->saved = tos;
  344. ctx->stack = buf;
  345. backdrop = pdf14_find_backdrop_buf(ctx);
  346. if (backdrop == NULL) {
  347. memset(buf->data, 0, buf->planestride * (buf->n_chan +
  348. (buf->has_shape ? 1 : 0)));
  349. } else {
  350. /* make copy of backdrop for compositing */
  351. byte *buf_plane = buf->data;
  352. byte *tos_plane = tos->data + buf->rect.p.x - tos->rect.p.x +
  353. (buf->rect.p.y - tos->rect.p.y) * tos->rowstride;
  354. int width = buf->rect.q.x - buf->rect.p.x;
  355. int y0 = buf->rect.p.y;
  356. int y1 = buf->rect.q.y;
  357. int i;
  358. int n_chan_copy = buf->n_chan + (tos->has_shape ? 1 : 0);
  359. for (i = 0; i < n_chan_copy; i++) {
  360. byte *buf_ptr = buf_plane;
  361. byte *tos_ptr = tos_plane;
  362. int y;
  363. for (y = y0; y < y1; ++y) {
  364. memcpy (buf_ptr, tos_ptr, width);
  365. buf_ptr += buf->rowstride;
  366. tos_ptr += tos->rowstride;
  367. }
  368. buf_plane += buf->planestride;
  369. tos_plane += tos->planestride;
  370. }
  371. if (has_shape && !tos->has_shape)
  372. memset (buf_plane, 0, buf->planestride);
  373. }
  374. return 0;
  375. }
  376. private int
  377. pdf14_pop_transparency_group(pdf14_ctx *ctx)
  378. {
  379. pdf14_buf *tos = ctx->stack;
  380. pdf14_buf *nos = tos->saved;
  381. pdf14_buf *maskbuf = ctx->maskbuf;
  382. int y0 = tos->rect.p.y;
  383. int y1 = tos->rect.q.y;
  384. if (y0 < y1) {
  385. int x0 = tos->rect.p.x;
  386. int x1 = tos->rect.q.x;
  387. int n_chan = ctx->n_chan;
  388. int num_comp = n_chan - 1;
  389. byte alpha = tos->alpha;
  390. byte shape = tos->shape;
  391. byte blend_mode = tos->blend_mode;
  392. byte *tos_ptr = tos->data;
  393. byte *nos_ptr = nos->data + x0 - nos->rect.p.x +
  394. (y0 - nos->rect.p.y) * nos->rowstride;
  395. byte *mask_ptr = NULL;
  396. int tos_planestride = tos->planestride;
  397. int nos_planestride = nos->planestride;
  398. int mask_planestride = 0x0badf00d; /* Quiet compiler. */
  399. byte mask_bg_alpha = 0; /* Quiet compiler. */
  400. int width = x1 - x0;
  401. int x, y;
  402. int i;
  403. byte tos_pixel[PDF14_MAX_PLANES];
  404. byte nos_pixel[PDF14_MAX_PLANES];
  405. bool tos_isolated = tos->isolated;
  406. bool nos_knockout = nos->knockout;
  407. byte *nos_alpha_g_ptr;
  408. int tos_shape_offset = n_chan * tos_planestride;
  409. int tos_alpha_g_offset = tos_shape_offset +
  410. (tos->has_shape ? tos_planestride : 0);
  411. int nos_shape_offset = n_chan * nos_planestride;
  412. bool nos_has_shape = nos->has_shape;
  413. byte *mask_tr_fn = NULL; /* Quiet compiler. */
  414. bool additive = ctx->additive;
  415. if (nos == NULL)
  416. return_error(gs_error_rangecheck);
  417. rect_merge(nos->bbox, tos->bbox);
  418. if_debug6('v', "pdf14_pop_transparency_group y0 = %d, y1 = %d, w = %d, alpha = %d, shape = %d, bm = %d\n",
  419. y0, y1, width, alpha, shape, blend_mode);
  420. if (nos->has_alpha_g)
  421. nos_alpha_g_ptr = nos_ptr + n_chan * nos_planestride;
  422. else
  423. nos_alpha_g_ptr = NULL;
  424. if (maskbuf != NULL) {
  425. mask_ptr = maskbuf->data + x0 - maskbuf->rect.p.x +
  426. (y0 - maskbuf->rect.p.y) * maskbuf->rowstride;
  427. mask_planestride = maskbuf->planestride;
  428. mask_bg_alpha = maskbuf->alpha;
  429. mask_tr_fn = maskbuf->transfer_fn;
  430. }
  431. for (y = y0; y < y1; ++y) {
  432. for (x = 0; x < width; ++x) {
  433. byte pix_alpha = alpha;
  434. /* Complement the components for subtractive color spaces */
  435. if (additive) {
  436. for (i = 0; i < n_chan; ++i) {
  437. tos_pixel[i] = tos_ptr[x + i * tos_planestride];
  438. nos_pixel[i] = nos_ptr[x + i * nos_planestride];
  439. }
  440. } else {
  441. for (i = 0; i < num_comp; ++i) {
  442. tos_pixel[i] = 255 - tos_ptr[x + i * tos_planestride];
  443. nos_pixel[i] = 255 - nos_ptr[x + i * nos_planestride];
  444. }
  445. tos_pixel[num_comp] = tos_ptr[x + num_comp * tos_planestride];
  446. nos_pixel[num_comp] = nos_ptr[x + num_comp * nos_planestride];
  447. }
  448. if (mask_ptr != NULL) {
  449. int mask_alpha = mask_ptr[x + num_comp * mask_planestride];
  450. int tmp;
  451. byte mask;
  452. /*
  453. * The mask data is really monochrome. Thus for additive (RGB)
  454. * we use the R channel for alpha since R = G = B. For
  455. * subtractive (CMYK) we use the K channel.
  456. */
  457. if (mask_alpha == 255) {
  458. /* todo: rgba->mask */
  459. mask = additive ? mask_ptr[x]
  460. : 255 - mask_ptr[x + 3 * mask_planestride];
  461. } else if (mask_alpha == 0)
  462. mask = mask_bg_alpha;
  463. else {
  464. int t2 = additive ? mask_ptr[x]
  465. : 255 - mask_ptr[x + 3 * mask_planestride];
  466. t2 = (t2 - mask_bg_alpha) * mask_alpha + 0x80;
  467. mask = mask_bg_alpha + ((t2 + (t2 >> 8)) >> 8);
  468. }
  469. mask = mask_tr_fn[mask];
  470. tmp = pix_alpha * mask + 0x80;
  471. pix_alpha = (tmp + (tmp >> 8)) >> 8;
  472. }
  473. if (nos_knockout) {
  474. byte *nos_shape_ptr = nos_has_shape ?
  475. &nos_ptr[x + nos_shape_offset] : NULL;
  476. byte tos_shape = tos_ptr[x + tos_shape_offset];
  477. art_pdf_composite_knockout_isolated_8(nos_pixel,
  478. nos_shape_ptr,
  479. tos_pixel,
  480. n_chan - 1,
  481. tos_shape,
  482. pix_alpha, shape);
  483. } else if (tos_isolated) {
  484. art_pdf_composite_group_8(nos_pixel, nos_alpha_g_ptr,
  485. tos_pixel,
  486. n_chan - 1,
  487. pix_alpha, blend_mode);
  488. } else {
  489. byte tos_alpha_g = tos_ptr[x + tos_alpha_g_offset];
  490. art_pdf_recomposite_group_8(nos_pixel, nos_alpha_g_ptr,
  491. tos_pixel, tos_alpha_g,
  492. n_chan - 1,
  493. pix_alpha, blend_mode);
  494. }
  495. if (nos_has_shape) {
  496. nos_ptr[x + nos_shape_offset] =
  497. art_pdf_union_mul_8 (nos_ptr[x + nos_shape_offset],
  498. tos_ptr[x + tos_shape_offset],
  499. shape);
  500. }
  501. /* Complement the results for subtractive color spaces */
  502. if (additive) {
  503. for (i = 0; i < n_chan; ++i) {
  504. nos_ptr[x + i * nos_planestride] = nos_pixel[i];
  505. }
  506. } else {
  507. for (i = 0; i < num_comp; ++i)
  508. nos_ptr[x + i * nos_planestride] = 255 - nos_pixel[i];
  509. nos_ptr[x + num_comp * nos_planestride] = nos_pixel[num_comp];
  510. }
  511. if (nos_alpha_g_ptr != NULL)
  512. ++nos_alpha_g_ptr;
  513. }
  514. tos_ptr += tos->rowstride;
  515. nos_ptr += nos->rowstride;
  516. if (nos_alpha_g_ptr != NULL)
  517. nos_alpha_g_ptr += nos->rowstride - width;
  518. if (mask_ptr != NULL)
  519. mask_ptr += maskbuf->rowstride;
  520. }
  521. }
  522. ctx->stack = nos;
  523. if_debug0('v', "[v]pop buf\n");
  524. pdf14_buf_free(tos, ctx->memory);
  525. if (maskbuf != NULL) {
  526. pdf14_buf_free(maskbuf, ctx->memory);
  527. ctx->maskbuf = NULL;
  528. }
  529. return 0;
  530. }
  531. private int
  532. pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, byte bg_alpha,
  533. byte *transfer_fn)
  534. {
  535. pdf14_buf *buf;
  536. if_debug0('v', "[v]pdf_push_transparency_mask\n");
  537. buf = pdf14_buf_new(rect, false, false, ctx->n_chan, ctx->memory);
  538. if (buf == NULL)
  539. return_error(gs_error_VMerror);
  540. /* fill in, but these values aren't really used */
  541. buf->isolated = true;
  542. buf->knockout = false;
  543. buf->alpha = bg_alpha;
  544. buf->shape = 0xff;
  545. buf->blend_mode = BLEND_MODE_Normal;
  546. buf->transfer_fn = transfer_fn;
  547. buf->saved = ctx->stack;
  548. ctx->stack = buf;
  549. memset(buf->data, 0, buf->planestride * buf->n_chan);
  550. return 0;
  551. }
  552. private int
  553. pdf14_pop_transparency_mask(pdf14_ctx *ctx)
  554. {
  555. pdf14_buf *tos = ctx->stack;
  556. ctx->stack = tos->saved;
  557. ctx->maskbuf = tos;
  558. return 0;
  559. }
  560. private int
  561. pdf14_open(gx_device *dev)
  562. {
  563. pdf14_device *pdev = (pdf14_device *)dev;
  564. gs_int_rect rect;
  565. if_debug2('v', "[v]pdf14_open: width = %d, height = %d\n",
  566. dev->width, dev->height);
  567. rect.p.x = 0;
  568. rect.p.y = 0;
  569. rect.q.x = dev->width;
  570. rect.q.y = dev->height;
  571. pdev->ctx = pdf14_ctx_new(&rect, dev->color_info.num_components + 1,
  572. pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, dev->memory);
  573. if (pdev->ctx == NULL)
  574. return_error(gs_error_VMerror);
  575. return 0;
  576. }
  577. /*
  578. * Encode a list of colorant values into a gx_color_index_value.
  579. */
  580. private gx_color_index
  581. pdf14_encode_color(gx_device *dev, const gx_color_value colors[])
  582. {
  583. int drop = sizeof(gx_color_value) * 8 - 8;
  584. gx_color_index color = 0;
  585. int i;
  586. int ncomp = dev->color_info.num_components;
  587. for (i = 0; i < ncomp; i++) {
  588. color <<= 8;
  589. color |= (colors[i] >> drop);
  590. }
  591. return (color == gx_no_color_index ? color ^ 1 : color);
  592. }
  593. /*
  594. * Decode a gx_color_index value back to a list of colorant values.
  595. */
  596. private int
  597. pdf14_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out)
  598. {
  599. int i;
  600. int ncomp = dev->color_info.num_components;
  601. for (i = 0; i < ncomp; i++) {
  602. out[ncomp - i - 1] = (gx_color_value) ((color & 0xff) * 0x101);
  603. color >>= 8;
  604. }
  605. return 0;
  606. }
  607. #ifdef DUMP_TO_PNG
  608. /* Dumps a planar RGBA image to a PNG file. */
  609. private int
  610. dump_planar_rgba(gs_memory_t *mem,
  611. const byte *buf, int width, int height, int rowstride, int planestride)
  612. {
  613. int rowbytes = width << 2;
  614. byte *row = gs_malloc(mem, rowbytes, 1, "png raster buffer");
  615. png_struct *png_ptr =
  616. png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  617. png_info *info_ptr =
  618. png_create_info_struct(png_ptr);
  619. const char *software_key = "Software";
  620. char software_text[256];
  621. png_text text_png;
  622. const byte *buf_ptr = buf;
  623. FILE *file;
  624. int code;
  625. int y;
  626. file = fopen ("c:\\temp\\tmp.png", "wb");
  627. if_debug0('v', "[v]pnga_output_page\n");
  628. if (row == 0 || png_ptr == 0 || info_ptr == 0) {
  629. code = gs_note_error(gs_error_VMerror);
  630. goto done;
  631. }
  632. /* set error handling */
  633. if (setjmp(png_ptr->jmpbuf)) {
  634. /* If we get here, we had a problem reading the file */
  635. code = gs_note_error(gs_error_VMerror);
  636. goto done;
  637. }
  638. code = 0; /* for normal path */
  639. /* set up the output control */
  640. png_init_io(png_ptr, file);
  641. /* set the file information here */
  642. info_ptr->width = width;
  643. info_ptr->height = height;
  644. /* resolution is in pixels per meter vs. dpi */
  645. info_ptr->x_pixels_per_unit =
  646. (png_uint_32) (96.0 * (100.0 / 2.54));
  647. info_ptr->y_pixels_per_unit =
  648. (png_uint_32) (96.0 * (100.0 / 2.54));
  649. info_ptr->phys_unit_type = PNG_RESOLUTION_METER;
  650. info_ptr->valid |= PNG_INFO_pHYs;
  651. /* At present, only supporting 32-bit rgba */
  652. info_ptr->bit_depth = 8;
  653. info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
  654. /* add comment */
  655. sprintf(software_text, "%s %d.%02d", gs_product,
  656. (int)(gs_revision / 100), (int)(gs_revision % 100));
  657. text_png.compression = -1; /* uncompressed */
  658. text_png.key = (char *)software_key; /* not const, unfortunately */
  659. text_png.text = software_text;
  660. text_png.text_length = strlen(software_text);
  661. info_ptr->text = &text_png;
  662. info_ptr->num_text = 1;
  663. /* write the file information */
  664. png_write_info(png_ptr, info_ptr);
  665. /* don't write the comments twice */
  666. info_ptr->num_text = 0;
  667. info_ptr->text = NULL;
  668. /* Write the contents of the image. */
  669. for (y = 0; y < height; ++y) {
  670. int x;
  671. for (x = 0; x < width; ++x) {
  672. row[(x << 2)] = buf_ptr[x];
  673. row[(x << 2) + 1] = buf_ptr[x + planestride];
  674. row[(x << 2) + 2] = buf_ptr[x + planestride * 2];
  675. row[(x << 2) + 3] = buf_ptr[x + planestride * 3];
  676. }
  677. png_write_row(png_ptr, row);
  678. buf_ptr += rowstride;
  679. }
  680. /* write the rest of the file */
  681. png_write_end(png_ptr, info_ptr);
  682. done:
  683. /* free the structures */
  684. png_destroy_write_struct(&png_ptr, &info_ptr);
  685. gs_free(mem, row, rowbytes, 1, "png raster buffer");
  686. fclose (file);
  687. return code;
  688. }
  689. #endif
  690. /**
  691. * pdf14_put_image: Put rendered image to target device.
  692. * @pdev: The PDF 1.4 rendering device.
  693. * @pgs: State for image draw operation.
  694. * @target: The target device.
  695. *
  696. * Puts the rendered image in @pdev's buffer to @target. This is called
  697. * as part of the sequence of popping the PDF 1.4 device filter.
  698. *
  699. * Return code: negative on error.
  700. **/
  701. private int
  702. pdf14_put_image(pdf14_device *pdev, gs_imager_state *pis, gx_device *target)
  703. {
  704. int code;
  705. gs_image1_t image;
  706. gs_matrix pmat;
  707. gx_image_enum_common_t *info;
  708. int width = pdev->width;
  709. int height = pdev->height;
  710. int y;
  711. pdf14_buf *buf = pdev->ctx->stack;
  712. int planestride = buf->planestride;
  713. int num_comp = buf->n_chan - 1;
  714. byte *buf_ptr = buf->data;
  715. byte *linebuf;
  716. gs_color_space cs;
  717. const byte bg = pdev->ctx->additive ? 255 : 0;
  718. #ifdef DUMP_TO_PNG
  719. dump_planar_rgba(pdev->memory, buf_ptr, width, height,
  720. buf->rowstride, buf->planestride);
  721. #endif
  722. #if 0
  723. /* Set graphics state device to target, so that image can set up
  724. the color mapping properly. */
  725. rc_increment(pdev);
  726. gs_setdevice_no_init(pgs, target);
  727. #endif
  728. if_debug0('v', "[v]pdf14_put_image\n");
  729. /*
  730. * Set color space to either Gray, RGB, or CMYK in preparation for sending
  731. * an image.
  732. */
  733. switch (num_comp) {
  734. case 1: /* DeviceGray */
  735. gs_cspace_init_DeviceGray(pis->memory, &cs);
  736. break;
  737. case 3: /* DeviceRGB */
  738. gs_cspace_init_DeviceRGB(pis->memory, &cs);
  739. break;
  740. case 4: /* DeviceCMYK */
  741. gs_cspace_init_DeviceCMYK(pis->memory, &cs);
  742. break;
  743. default: /* Should never occur */
  744. return_error(gs_error_rangecheck);
  745. break;
  746. }
  747. gs_image_t_init_adjust(&image, &cs, false);
  748. image.ImageMatrix.xx = (float)width;
  749. image.ImageMatrix.yy = (float)height;
  750. image.Width = width;
  751. image.Height = height;
  752. image.BitsPerComponent = 8;
  753. pmat.xx = (float)width;
  754. pmat.xy = 0;
  755. pmat.yx = 0;
  756. pmat.yy = (float)height;
  757. pmat.tx = 0;
  758. pmat.ty = 0;
  759. code = dev_proc(target, begin_typed_image) (target,
  760. pis, &pmat,
  761. (gs_image_common_t *)&image,
  762. NULL, NULL, NULL,
  763. pis->memory, &info);
  764. if (code < 0)
  765. return code;
  766. linebuf = gs_alloc_bytes(pdev->memory, width * num_comp, "pdf14_put_image");
  767. for (y = 0; y < height; y++) {
  768. gx_image_plane_t planes;
  769. int x;
  770. int rows_used;
  771. for (x = 0; x < width; x++) {
  772. byte comp, a;
  773. int tmp, comp_num;
  774. /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
  775. a = buf_ptr[x + planestride * num_comp];
  776. if ((a + 1) & 0xfe) {
  777. a ^= 0xff;
  778. for (comp_num = 0; comp_num < num_comp; comp_num++) {
  779. comp = buf_ptr[x + planestride * comp_num];
  780. tmp = ((bg - comp) * a) + 0x80;
  781. comp += (tmp + (tmp >> 8)) >> 8;
  782. linebuf[x * num_comp + comp_num] = comp;
  783. }
  784. } else if (a == 0) {
  785. for (comp_num = 0; comp_num < num_comp; comp_num++) {
  786. linebuf[x * num_comp + comp_num] = bg;
  787. }
  788. } else {
  789. for (comp_num = 0; comp_num < num_comp; comp_num++) {
  790. comp = buf_ptr[x + planestride * comp_num];
  791. linebuf[x * num_comp + comp_num] = comp;
  792. }
  793. }
  794. }
  795. planes.data = linebuf;
  796. planes.data_x = 0;
  797. planes.raster = width * num_comp;
  798. info->procs->plane_data(info, &planes, 1, &rows_used);
  799. /* todo: check return value */
  800. buf_ptr += buf->rowstride;
  801. }
  802. gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
  803. info->procs->end_image(info, true);
  804. #if 0
  805. /* Restore device in graphics state.*/
  806. gs_setdevice_no_init(pgs, (gx_device*) pdev);
  807. rc_decrement_only(pdev, "pdf_14_put_image");
  808. #endif
  809. return code;
  810. }
  811. private int
  812. pdf14_close(gx_device *dev)
  813. {
  814. pdf14_device *pdev = (pdf14_device *)dev;
  815. if (pdev->ctx) {
  816. pdf14_ctx_free(pdev->ctx);
  817. pdev->ctx = NULL;
  818. }
  819. return 0;
  820. }
  821. private int
  822. pdf14_output_page(gx_device * dev, int num_copies, int flush)
  823. {
  824. pdf14_device * pdev = (pdf14_device *)dev;
  825. if (pdev->target != NULL)
  826. return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
  827. return 0;
  828. }
  829. #define COPY_PARAM(p) dev->p = target->p
  830. #define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
  831. /*
  832. * Copy device parameters back from a target. This copies all standard
  833. * parameters related to page size and resolution, but not any of the
  834. * color-related parameters, as the pdf14 device retains its own color
  835. * handling. This routine is parallel to gx_device_copy_params().
  836. */
  837. private void
  838. gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
  839. {
  840. COPY_PARAM(width);
  841. COPY_PARAM(height);
  842. COPY_ARRAY_PARAM(MediaSize);
  843. COPY_ARRAY_PARAM(ImagingBBox);
  844. COPY_PARAM(ImagingBBox_set);
  845. COPY_ARRAY_PARAM(HWResolution);
  846. COPY_ARRAY_PARAM(MarginsHWResolution);
  847. COPY_ARRAY_PARAM(Margins);
  848. COPY_ARRAY_PARAM(HWMargins);
  849. COPY_PARAM(PageCount);
  850. #undef COPY_ARRAY_PARAM
  851. #undef COPY_PARAM
  852. }
  853. /*
  854. * This is a forwarding version of the put_params device proc. It is only
  855. * used when the PDF 1.4 compositor devices are closed. The routine will
  856. * check if the target device has closed and, if so, close itself. The routine
  857. * also sync the device parameters.
  858. */
  859. private int
  860. pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
  861. {
  862. pdf14_device * pdev = (pdf14_device *)dev;
  863. gx_device * tdev = pdev->target;
  864. int code = 0;
  865. if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
  866. gx_device_decache_colors(dev);
  867. if (!tdev->is_open)
  868. code = gs_closedevice(dev);
  869. gx_device_copy_params(dev, tdev);
  870. }
  871. return code;
  872. }
  873. /*
  874. * The put_params method for the PDF 1.4 device will check if the
  875. * target device has closed and, if so, close itself. Note: This routine is
  876. * currently being used by both the pdf14_clist_device and the pdf_device.
  877. * Please make sure that any changes are either applicable to both devices
  878. * or clone the routine for each device.
  879. */
  880. private int
  881. pdf14_put_params(gx_device * dev, gs_param_list * plist)
  882. {
  883. pdf14_device * pdev = (pdf14_device *)dev;
  884. gx_device * tdev = pdev->target;
  885. int code = 0;
  886. if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
  887. gx_device_decache_colors(dev);
  888. if (!tdev->is_open)
  889. code = gs_closedevice(dev);
  890. gs_pdf14_device_copy_params(dev, tdev);
  891. }
  892. return code;
  893. }
  894. /*
  895. * Copy marking related parameters into the PDF 1.4 device structure for use
  896. * by pdf14_fill_rrectangle.
  897. */
  898. private void
  899. pdf14_set_marking_params(gx_device *dev, const gs_imager_state *pis)
  900. {
  901. pdf14_device * pdev = (pdf14_device *)dev;
  902. pdev->opacity = pis->opacity.alpha;
  903. pdev->shape = pis->shape.alpha;
  904. pdev->alpha = pis->opacity.alpha * pis->shape.alpha;
  905. pdev->blend_mode = pis->blend_mode;
  906. if_debug3('v', "[v]set_marking_params, opacity = %g, shape = %g, bm = %d\n",
  907. pdev->opacity, pdev->shape, pis->blend_mode);
  908. }
  909. private int
  910. pdf14_fill_path(gx_device *dev, const gs_imager_state *pis,
  911. gx_path *ppath, const gx_fill_params *params,
  912. const gx_drawing_color *pdcolor,
  913. const gx_clip_path *pcpath)
  914. {
  915. gs_imager_state new_is = *pis;
  916. /*
  917. * The blend operations are not idempotent. Force non-idempotent
  918. * filling and stroking operations.
  919. */
  920. new_is.log_op |= lop_pdf14;
  921. pdf14_set_marking_params(dev, pis);
  922. return gx_default_fill_path(dev, &new_is, ppath, params, pdcolor, pcpath);
  923. }
  924. private int
  925. pdf14_stroke_path(gx_device *dev, const gs_imager_state *pis,
  926. gx_path *ppath, const gx_stroke_params *params,
  927. const gx_drawing_color *pdcolor,
  928. const gx_clip_path *pcpath)
  929. {
  930. gs_imager_state new_is = *pis;
  931. /*
  932. * The blend operations are not idempotent. Force non-idempotent
  933. * filling and stroking operations.
  934. */
  935. new_is.log_op |= lop_pdf14;
  936. pdf14_set_marking_params(dev, pis);
  937. return gx_default_stroke_path(dev, &new_is, ppath, params, pdcolor,
  938. pcpath);
  939. }
  940. private int
  941. pdf14_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
  942. const gs_matrix *pmat, const gs_image_common_t *pic,
  943. const gs_int_rect * prect,
  944. const gx_drawing_color * pdcolor,
  945. const gx_clip_path * pcpath, gs_memory_t * mem,
  946. gx_image_enum_common_t ** pinfo)
  947. {
  948. pdf14_set_marking_params(dev, pis);
  949. return gx_default_begin_typed_image(dev, pis, pmat, pic, prect, pdcolor,
  950. pcpath, mem, pinfo);
  951. }
  952. private void
  953. pdf14_set_params(gs_imager_state * pis, gx_device * dev,
  954. const gs_pdf14trans_params_t * pparams)
  955. {
  956. if (pparams->changed & PDF14_SET_BLEND_MODE)
  957. pis->blend_mode = pparams->blend_mode;
  958. if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
  959. pis->text_knockout = pparams->text_knockout;
  960. if (pparams->changed & PDF14_SET_SHAPE_ALPHA)
  961. pis->shape.alpha = pparams->shape.alpha;
  962. if (pparams->changed & PDF14_SET_OPACITY_ALPHA)
  963. pis->opacity.alpha = pparams->opacity.alpha;
  964. pdf14_set_marking_params(dev, pis);
  965. }
  966. /*
  967. * This open_device method for the PDF 1.4 compositor devices is only used
  968. * when these devices are disabled. This routine is about as close to
  969. * a pure "forwarding" open_device operation as is possible. Its only
  970. * significant function is to ensure that the is_open field of the
  971. * PDF 1.4 compositor devices matches that of the target device.
  972. *
  973. * We assume this procedure is called only if the device is not already
  974. * open, and that gs_opendevice will take care of the is_open flag.
  975. */
  976. private int
  977. pdf14_forward_open_device(gx_device * dev)
  978. {
  979. gx_device_forward * pdev = (gx_device_forward *)dev;
  980. gx_device * tdev = pdev->target;
  981. int code = 0;
  982. /* The PDF 1.4 compositing devices must have a target */
  983. if (tdev == 0)
  984. return_error(gs_error_unknownerror);
  985. if ((code = gs_opendevice(tdev)) >= 0)
  986. gx_device_copy_params(dev, tdev);
  987. return code;
  988. }
  989. /*
  990. * Convert all device procs to be 'forwarding'. The caller is responsible
  991. * for setting any device procs that should not be forwarded.
  992. */
  993. private void
  994. pdf14_forward_device_procs(gx_device * dev)
  995. {
  996. gx_device_forward * pdev = (gx_device_forward *)dev;
  997. /*
  998. * We are using gx_device_forward_fill_in_procs to set the various procs.
  999. * This will ensure that any new device procs are also set. However that
  1000. * routine only changes procs which are NULL. Thus we start by setting all
  1001. * procs to NULL.
  1002. */
  1003. memset(&(pdev->procs), 0, size_of(pdev->procs));
  1004. gx_device_forward_fill_in_procs(pdev);
  1005. /*
  1006. * gx_device_forward_fill_in_procs does not forward all procs.
  1007. * Set the remainding procs to also forward.
  1008. */
  1009. set_dev_proc(dev, close_device, gx_forward_close_device);
  1010. set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
  1011. set_dev_proc(dev, tile_rectangle, gx_forward_tile_rectangle);
  1012. set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
  1013. set_dev_proc(dev, copy_color, gx_forward_copy_color);
  1014. set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
  1015. set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
  1016. set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
  1017. /* These are forwarding devices with minor tweaks. */
  1018. set_dev_proc(dev, open_device, pdf14_forward_open_device);
  1019. set_dev_proc(dev, put_params, pdf14_forward_put_params);
  1020. }
  1021. /*
  1022. * Disable the PDF 1.4 compositor device. Once created, the PDF 1.4
  1023. * compositor device is never removed. (We do not have a remove compositor
  1024. * method.) However it is no-op'ed when the PDF 1.4 device is popped. This
  1025. * routine implements that action.
  1026. */
  1027. private int
  1028. pdf14_disable_device(gx_device * dev)
  1029. {
  1030. gx_device_forward * pdev = (gx_device_forward *)dev;
  1031. if_debug0('v', "[v]pdf14_disable_device\n");
  1032. dev->color_info = pdev->target->color_info;
  1033. pdf14_forward_device_procs(dev);
  1034. set_dev_proc(dev, create_compositor, pdf14_forward_create_compositor);
  1035. return 0;
  1036. }
  1037. /*
  1038. * The default color space for PDF 1.4 blend modes is based upon the process
  1039. * color model of the output device.
  1040. */
  1041. private pdf14_default_colorspace_t
  1042. pdf14_determine_default_blend_cs(gx_device * pdev)
  1043. {
  1044. if (pdev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
  1045. /* Use DeviceCMYK for all subrtactive process color models. */
  1046. return DeviceCMYK;
  1047. else {
  1048. /*
  1049. * Note: We do not allow the SeparationOrder device parameter for
  1050. * additive devices. Thus we always have 1 colorant for DeviceGray
  1051. * and 3 colorants for DeviceRGB. We do not currently support
  1052. * blending in a DeviceGray color space. Thus we oniy use DeviceRGB.
  1053. */
  1054. return DeviceRGB;
  1055. }
  1056. }
  1057. /*
  1058. * the PDF 1.4 transparency spec says that color space for blending
  1059. * operations can be based upon either a color space specified in the
  1060. * group or a default value based upon the output device. We are
  1061. * currently only using a color space based upon the device.
  1062. */
  1063. private int
  1064. get_pdf14_device_proto(gx_device * dev,
  1065. const pdf14_device ** pdevproto)
  1066. {
  1067. pdf14_default_colorspace_t dev_cs =
  1068. pdf14_determine_default_blend_cs(dev);
  1069. switch (dev_cs) {
  1070. case DeviceGray:
  1071. *pdevproto = &gs_pdf14_Gray_device;
  1072. break;
  1073. case DeviceRGB:
  1074. *pdevproto = &gs_pdf14_RGB_device;
  1075. break;
  1076. case DeviceCMYK:
  1077. *pdevproto = &gs_pdf14_CMYK_device;
  1078. break;
  1079. default: /* Should not occur */
  1080. return_error(gs_error_rangecheck);
  1081. }
  1082. return 0;
  1083. }
  1084. /*
  1085. * Recreate the PDF 1.4 compositor device. Once created, the PDF 1.4
  1086. * compositor device is never removed. (We do not have a remove compositor
  1087. * method.) However it is no-op'ed when the PDF 1.4 device is popped. This
  1088. * routine will re-enable the compositor if the PDF 1.4 device is pushed
  1089. * again.
  1090. */
  1091. private int
  1092. pdf14_recreate_device(gs_memory_t *mem, gs_imager_state * pis,
  1093. gx_device * dev)
  1094. {
  1095. pdf14_device * pdev = (pdf14_device *)dev;
  1096. gx_device * target = pdev->target;
  1097. const pdf14_device * dev_proto;
  1098. int code;
  1099. if_debug0('v', "[v]pdf14_recreate_device\n");
  1100. /*
  1101. * We will not use the entire prototype device but we will set the
  1102. * color related info and the device procs to match the prototype.
  1103. */
  1104. code = get_pdf14_device_proto(target, &dev_proto);
  1105. if (code < 0)
  1106. return code;
  1107. pdev->color_info = dev_proto->color_info;
  1108. pdev->procs = dev_proto->procs;
  1109. gx_device_fill_in_procs(dev);
  1110. check_device_separable((gx_device *)pdev);
  1111. return code;
  1112. }
  1113. /*
  1114. * Implement the various operations that can be specified via the PDF 1.4
  1115. * create compositor request.
  1116. */
  1117. private int
  1118. gx_update_pdf14_compositor(gx_device * pdev, gs_imager_state * pis,
  1119. const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
  1120. {
  1121. pdf14_device *p14dev = (pdf14_device *)pdev;
  1122. int code = 0;
  1123. switch (pdf14pct->params.pdf14_op) {
  1124. default: /* Should not occur. */
  1125. break;
  1126. case PDF14_PUSH_DEVICE:
  1127. p14dev->blend_mode = 0;
  1128. p14dev->opacity = p14dev->shape = 0.0;
  1129. pdf14_recreate_device(mem, pis, pdev);
  1130. break;
  1131. case PDF14_POP_DEVICE:
  1132. pis->get_cmap_procs = p14dev->save_get_cmap_procs;
  1133. gx_set_cmap_procs(pis, p14dev->target);
  1134. code = pdf14_put_image(p14dev, pis, p14dev->target);
  1135. pdf14_disable_device(pdev);
  1136. pdf14_close(pdev);
  1137. break;
  1138. case PDF14_BEGIN_TRANS_GROUP:
  1139. code = gx_begin_transparency_group(pis, pdev, &pdf14pct->params);
  1140. break;
  1141. case PDF14_END_TRANS_GROUP:
  1142. code = gx_end_transparency_group(pis, pdev);
  1143. break;
  1144. case PDF14_INIT_TRANS_MASK:
  1145. code = gx_init_transparency_mask(pis, &pdf14pct->params);
  1146. break;
  1147. case PDF14_BEGIN_TRANS_MASK:
  1148. code = gx_begin_transparency_mask(pis, pdev, &pdf14pct->params);
  1149. break;
  1150. case PDF14_END_TRANS_MASK:
  1151. code = gx_end_transparency_mask(pis, pdev, &pdf14pct->params);
  1152. break;
  1153. case PDF14_SET_BLEND_PARAMS:
  1154. pdf14_set_params(pis, pdev, &pdf14pct->params);
  1155. break;
  1156. }
  1157. return code;
  1158. }
  1159. /*
  1160. * The PDF 1.4 compositor is never removed. (We do not have a 'remove
  1161. * compositor' method. However the compositor is disabled when we are not
  1162. * doing a page which uses PDF 1.4 transparency. This routine is only active
  1163. * when the PDF 1.4 compositor is 'disabled'. It checks for reenabling the
  1164. * PDF 1.4 compositor. Otherwise it simply passes create compositor requests
  1165. * to the targer.
  1166. */
  1167. private int
  1168. pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev,
  1169. const gs_composite_t * pct, gs_imager_state * pis,
  1170. gs_memory_t * mem)
  1171. {
  1172. pdf14_device *pdev = (pdf14_device *)dev;
  1173. gx_device * tdev = pdev->target;
  1174. gx_device * ndev;
  1175. int code = 0;
  1176. *pcdev = dev;
  1177. if (gs_is_pdf14trans_compositor(pct)) {
  1178. const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
  1179. if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
  1180. return gx_update_pdf14_compositor(dev, pis, pdf14pct, mem);
  1181. return 0;
  1182. }
  1183. code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pis, mem);
  1184. if (code < 0)
  1185. return code;
  1186. pdev->target = ndev;
  1187. return 0;
  1188. }
  1189. /*
  1190. * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
  1191. * and return. Since the gs_pdf14_device only supports the high-level routines
  1192. * of the interface, don't bother trying to handle any other compositor.
  1193. */
  1194. private int
  1195. pdf14_create_compositor(gx_device * dev, gx_device * * pcdev,
  1196. const gs_composite_t * pct, gs_imager_state * pis,
  1197. gs_memory_t * mem)
  1198. {
  1199. if (gs_is_pdf14trans_compositor(pct)) {
  1200. const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
  1201. *pcdev = dev;
  1202. return gx_update_pdf14_compositor(dev, pis, pdf14pct, mem);
  1203. } else if (gs_is_overprint_compositor(pct)) {
  1204. *pcdev = dev;
  1205. return 0;
  1206. } else
  1207. return gx_no_create_compositor(dev, pcdev, pct, pis, mem);
  1208. }
  1209. private int
  1210. pdf14_text_begin(gx_device * dev, gs_imager_state * pis,
  1211. const gs_text_params_t * text, gs_font * font,
  1212. gx_path * path, const gx_device_color * pdcolor,
  1213. const gx_clip_path * pcpath, gs_memory_t * memory,
  1214. gs_text_enum_t ** ppenum)
  1215. {
  1216. int code;
  1217. gs_text_enum_t *penum;
  1218. if_debug0('v', "[v]pdf14_text_begin\n");
  1219. pdf14_set_marking_params(dev, pis);
  1220. code = gx_default_text_begin(dev, pis, text, font, path, pdcolor, pcpath,
  1221. memory, &penum);
  1222. if (code < 0)
  1223. return code;
  1224. *ppenum = (gs_text_enum_t *)penum;
  1225. return code;
  1226. }
  1227. private int
  1228. pdf14_fill_rectangle(gx_device * dev,
  1229. int x, int y, int w, int h, gx_color_index color)
  1230. {
  1231. pdf14_device *pdev = (pdf14_device *)dev;
  1232. pdf14_buf *buf = pdev->ctx->stack;
  1233. fit_fill_xywh(dev, x, y, w, h);
  1234. if (w <= 0 || h <= 0)
  1235. return 0;
  1236. if (buf->knockout)
  1237. return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color);
  1238. else
  1239. return pdf14_mark_fill_rectangle(dev, x, y, w, h, color);
  1240. }
  1241. private int
  1242. pdf14_begin_transparency_group(gx_device *dev,
  1243. const gs_transparency_group_params_t *ptgp,
  1244. const gs_rect *pbbox,
  1245. gs_imager_state *pis,
  1246. gs_transparency_state_t **ppts,
  1247. gs_memory_t *mem)
  1248. {
  1249. pdf14_device *pdev = (pdf14_device *)dev;
  1250. double alpha = pis->opacity.alpha * pis->shape.alpha;
  1251. gs_rect dev_bbox;
  1252. gs_int_rect rect;
  1253. int code;
  1254. code = gs_bbox_transform(pbbox, &ctm_only(pis), &dev_bbox);
  1255. if (code < 0)
  1256. return code;
  1257. rect.p.x = (int)floor(dev_bbox.p.x);
  1258. rect.p.y = (int)floor(dev_bbox.p.y);
  1259. rect.q.x = (int)ceil(dev_bbox.q.x);
  1260. rect.q.y = (int)ceil(dev_bbox.q.y);
  1261. rect_intersect(rect, pdev->ctx->rect);
  1262. if_debug4('v', "[v]begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d\n",
  1263. ptgp->Isolated, ptgp->Knockout, alpha, pis->blend_mode);
  1264. code = pdf14_push_transparency_group(pdev->ctx, &rect,
  1265. ptgp->Isolated, ptgp->Knockout,
  1266. (byte)floor (255 * alpha + 0.5),
  1267. (byte)floor (255 * pis->shape.alpha + 0.5),
  1268. pis->blend_mode);
  1269. return code;
  1270. }
  1271. private int
  1272. pdf14_end_transparency_group(gx_device *dev,
  1273. gs_imager_state *pis,
  1274. gs_transparency_state_t **ppts)
  1275. {
  1276. pdf14_device *pdev = (pdf14_device *)dev;
  1277. int code;
  1278. if_debug0('v', "[v]end_transparency_group\n");
  1279. code = pdf14_pop_transparency_group(pdev->ctx);
  1280. return code;
  1281. }
  1282. private int
  1283. pdf14_begin_transparency_mask(gx_device *dev,
  1284. const gx_transparency_mask_params_t *ptmp,
  1285. const gs_rect *pbbox,
  1286. gs_imager_state *pis,
  1287. gs_transparency_state_t **ppts,
  1288. gs_memory_t *mem)
  1289. {
  1290. pdf14_device *pdev = (pdf14_device *)dev;
  1291. byte bg_alpha = 0;
  1292. byte *transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, 256,
  1293. "pdf14_push_transparency_mask");
  1294. if (ptmp->Background_components)
  1295. bg_alpha = (int)(255 * ptmp->Background[0] + 0.5);
  1296. if_debug1('v', "begin transparency mask, bg_alpha = %d\n", bg_alpha);
  1297. memcpy(transfer_fn, ptmp->transfer_fn, size_of(ptmp->transfer_fn));
  1298. return pdf14_push_transparency_mask(pdev->ctx, &pdev->ctx->rect, bg_alpha,
  1299. transfer_fn);
  1300. }
  1301. private int
  1302. pdf14_end_transparency_mask(gx_device *dev,
  1303. gs_transparency_mask_t **pptm)
  1304. {
  1305. pdf14_device *pdev = (pdf14_device *)dev;
  1306. if_debug0('v', "end transparency mask!\n");
  1307. return pdf14_pop_transparency_mask(pdev->ctx);
  1308. }
  1309. private int
  1310. pdf14_mark_fill_rectangle(gx_device * dev,
  1311. int x, int y, int w, int h, gx_color_index color)
  1312. {
  1313. pdf14_device *pdev = (pdf14_device *)dev;
  1314. pdf14_buf *buf = pdev->ctx->stack;
  1315. int i, j, k;
  1316. byte *line, *dst_ptr;
  1317. byte src[PDF14_MAX_PLANES];
  1318. byte dst[PDF14_MAX_PLANES];
  1319. gs_blend_mode_t blend_mode = pdev->blend_mode;
  1320. bool additive = pdev->ctx->additive;
  1321. int rowstride = buf->rowstride;
  1322. int planestride = buf->planestride;
  1323. bool has_alpha_g = buf->has_alpha_g;
  1324. bool has_shape = buf->has_shape;
  1325. int num_chan = buf->n_chan;
  1326. int num_comp = num_chan - 1;
  1327. int shape_off = num_chan * planestride;
  1328. int alpha_g_off = shape_off + (has_shape ? planestride : 0);
  1329. byte shape = 0; /* Quiet compiler. */
  1330. byte src_alpha;
  1331. if_debug7('v', "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %lx bm %d, nc %d,\n", x, y, w, h, color, blend_mode, num_chan);
  1332. /* Complement the components for subtractive color spaces */
  1333. if (additive) {
  1334. for (i = num_comp - 1; i >= 0; i--) {
  1335. src[i] = (byte)(color & 0xff);
  1336. color >>= 8;
  1337. }
  1338. }
  1339. else {
  1340. for (i = num_comp - 1; i >= 0; i--) {
  1341. src[i] = (byte)(0xff - (color & 0xff));
  1342. color >>= 8;
  1343. }
  1344. }
  1345. src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
  1346. if (has_shape)
  1347. shape = (byte)floor (255 * pdev->shape + 0.5);
  1348. if (x < buf->rect.p.x) x = buf->rect.p.x;
  1349. if (y < buf->rect.p.y) y = buf->rect.p.y;
  1350. if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
  1351. if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
  1352. if (x < buf->bbox.p.x) buf->bbox.p.x = x;
  1353. if (y < buf->bbox.p.y) buf->bbox.p.y = y;
  1354. if (x + w > buf->bbox.q.x) buf->bbox.q.x = x + w;
  1355. if (y + h > buf->bbox.q.y) buf->bbox.q.y = y + h;
  1356. line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
  1357. for (j = 0; j < h; ++j) {
  1358. dst_ptr = line;
  1359. for (i = 0; i < w; ++i) {
  1360. /* Complement the components for subtractive color spaces */
  1361. if (additive) {
  1362. for (k = 0; k < num_chan; ++k)
  1363. dst[k] = dst_ptr[k * planestride];
  1364. }
  1365. else { /* Complement the components for subtractive color spaces */
  1366. for (k = 0; k < num_comp; ++k)
  1367. dst[k] = 255 - dst_ptr[k * planestride];
  1368. dst[num_comp] = dst_ptr[num_comp * planestride];
  1369. }
  1370. art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode);
  1371. /* Complement the results for subtractive color spaces */
  1372. if (additive) {
  1373. for (k = 0; k < num_chan; ++k)
  1374. dst_ptr[k * planestride] = dst[k];
  1375. }
  1376. else {
  1377. for (k = 0; k < num_comp; ++k)
  1378. dst_ptr[k * planestride] = 255 - dst[k];
  1379. dst_ptr[num_comp * planestride] = dst[num_comp];
  1380. }
  1381. if (has_alpha_g) {
  1382. int tmp = (255 - dst_ptr[alpha_g_off]) * (255 - src_alpha) + 0x80;
  1383. dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
  1384. }
  1385. if (has_shape) {
  1386. int tmp = (255 - dst_ptr[shape_off]) * (255 - shape) + 0x80;
  1387. dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
  1388. }
  1389. ++dst_ptr;
  1390. }
  1391. line += rowstride;
  1392. }
  1393. return 0;
  1394. }
  1395. private int
  1396. pdf14_mark_fill_rectangle_ko_simple(gx_device * dev,
  1397. int x, int y, int w, int h, gx_color_index color)
  1398. {
  1399. pdf14_device *pdev = (pdf14_device *)dev;
  1400. pdf14_buf *buf = pdev->ctx->stack;
  1401. int i, j, k;
  1402. byte *line, *dst_ptr;
  1403. byte src[PDF14_MAX_PLANES];
  1404. byte dst[PDF14_MAX_PLANES];
  1405. int rowstride = buf->rowstride;
  1406. int planestride = buf->planestride;
  1407. int num_chan = buf->n_chan;
  1408. int num_comp = num_chan - 1;
  1409. int shape_off = num_chan * planestride;
  1410. bool has_shape = buf->has_shape;
  1411. byte opacity;
  1412. bool additive = pdev->ctx->additive;
  1413. if_debug6('v', "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx bm %d, nc %d,\n", x, y, w, h, color, num_chan);
  1414. /* Complement the components for subtractive color spaces */
  1415. if (additive) {
  1416. for (i = num_comp - 1; i >= 0; i--) {
  1417. src[i] = (byte)(color & 0xff);
  1418. color >>= 8;
  1419. }
  1420. }
  1421. else {
  1422. for (i = num_comp - 1; i >= 0; i--) {
  1423. src[i] = (byte)(0xff - (color & 0xff));
  1424. color >>= 8;
  1425. }
  1426. }
  1427. src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
  1428. opacity = (byte)floor (255 * pdev->opacity + 0.5);
  1429. if (x < buf->rect.p.x) x = buf->rect.p.x;
  1430. if (y < buf->rect.p.y) y = buf->rect.p.y;
  1431. if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
  1432. if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
  1433. if (x < buf->bbox.p.x) buf->bbox.p.x = x;
  1434. if (y < buf->bbox.p.y) buf->bbox.p.y = y;
  1435. if (x + w > buf->bbox.q.x) buf->bbox.q.x = x + w;
  1436. if (y + h > buf->bbox.q.y) buf->bbox.q.y = y + h;
  1437. line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
  1438. for (j = 0; j < h; ++j) {
  1439. dst_ptr = line;
  1440. for (i = 0; i < w; ++i) {
  1441. /* Complement the components for subtractive color spaces */
  1442. if (additive) {
  1443. for (k = 0; k < num_chan; ++k)
  1444. dst[k] = dst_ptr[k * planestride];
  1445. }
  1446. else {
  1447. for (k = 0; k < num_comp; ++k)
  1448. dst[k] = 255 - dst_ptr[k * planestride];
  1449. dst[num_comp] = dst_ptr[num_comp * planestride];
  1450. }
  1451. art_pdf_composite_knockout_simple_8(dst,
  1452. has_shape ? dst_ptr + shape_off : NULL, src, num_comp, opacity);
  1453. /* Complement the results for subtractive color spaces */
  1454. if (additive) {
  1455. for (k = 0; k < num_chan; ++k)
  1456. dst_ptr[k * planestride] = dst[k];
  1457. }
  1458. else {
  1459. for (k = 0; k < num_comp; ++k)
  1460. dst_ptr[k * planestride] = 255 - dst[k];
  1461. dst_ptr[num_comp * planestride] = dst[num_comp];
  1462. }
  1463. ++dst_ptr;
  1464. }
  1465. line += rowstride;
  1466. }
  1467. return 0;
  1468. }
  1469. /**
  1470. * Here we have logic to override the cmap_procs with versions that
  1471. * do not apply the transfer function. These copies should track the
  1472. * versions in gxcmap.c.
  1473. **/
  1474. private cmap_proc_gray(pdf14_cmap_gray_direct);
  1475. private cmap_proc_rgb(pdf14_cmap_rgb_direct);
  1476. private cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
  1477. private cmap_proc_rgb_alpha(pdf14_cmap_rgb_alpha_direct);
  1478. private cmap_proc_separation(pdf14_cmap_separation_direct);
  1479. private cmap_proc_devicen(pdf14_cmap_devicen_direct);
  1480. private cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
  1481. private const gx_color_map_procs pdf14_cmap_many = {
  1482. pdf14_cmap_gray_direct,
  1483. pdf14_cmap_rgb_direct,
  1484. pdf14_cmap_cmyk_direct,
  1485. pdf14_cmap_rgb_alpha_direct,
  1486. pdf14_cmap_separation_direct,
  1487. pdf14_cmap_devicen_direct,
  1488. pdf14_cmap_is_halftoned
  1489. };
  1490. /**
  1491. * Note: copied from gxcmap.c because it's inlined.
  1492. **/
  1493. private inline void
  1494. map_components_to_colorants(const frac * pcc,
  1495. const gs_devicen_color_map * pcolor_component_map, frac * plist)
  1496. {
  1497. int i = pcolor_component_map->num_colorants - 1;
  1498. int pos;
  1499. /* Clear all output colorants first */
  1500. for (; i >= 0; i--) {
  1501. plist[i] = frac_0;
  1502. }
  1503. /* Map color components into output list */
  1504. for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
  1505. pos = pcolor_component_map->color_map[i];
  1506. if (pos >= 0)
  1507. plist[pos] = pcc[i];
  1508. }
  1509. }
  1510. private void
  1511. pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_imager_state * pis,
  1512. gx_device * dev, gs_color_select_t select)
  1513. {
  1514. int i, ncomps = dev->color_info.num_components;
  1515. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1516. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1517. gx_color_index color;
  1518. /* map to the color model */
  1519. dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, gray, cm_comps);
  1520. for (i = 0; i < ncomps; i++)
  1521. cv[i] = frac2cv(cm_comps[i]);
  1522. /* encode as a color index */
  1523. color = dev_proc(dev, encode_color)(dev, cv);
  1524. /* check if the encoding was successful; we presume failure is rare */
  1525. if (color != gx_no_color_index)
  1526. color_set_pure(pdc, color);
  1527. }
  1528. private void
  1529. pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
  1530. const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
  1531. {
  1532. int i, ncomps = dev->color_info.num_components;
  1533. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1534. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1535. gx_color_index color;
  1536. /* map to the color model */
  1537. dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps);
  1538. for (i = 0; i < ncomps; i++)
  1539. cv[i] = frac2cv(cm_comps[i]);
  1540. /* encode as a color index */
  1541. color = dev_proc(dev, encode_color)(dev, cv);
  1542. /* check if the encoding was successful; we presume failure is rare */
  1543. if (color != gx_no_color_index)
  1544. color_set_pure(pdc, color);
  1545. }
  1546. private void
  1547. pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
  1548. const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
  1549. {
  1550. int i, ncomps = dev->color_info.num_components;
  1551. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1552. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1553. gx_color_index color;
  1554. /* map to the color model */
  1555. dev_proc(dev, get_color_mapping_procs)(dev)->map_cmyk(dev, c, m, y, k, cm_comps);
  1556. for (i = 0; i < ncomps; i++)
  1557. cv[i] = frac2cv(cm_comps[i]);
  1558. color = dev_proc(dev, encode_color)(dev, cv);
  1559. if (color != gx_no_color_index)
  1560. color_set_pure(pdc, color);
  1561. }
  1562. private void
  1563. pdf14_cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc,
  1564. const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
  1565. {
  1566. int i, ncomps = dev->color_info.num_components;
  1567. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1568. gx_color_value cv_alpha, cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1569. gx_color_index color;
  1570. /* map to the color model */
  1571. dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps);
  1572. /* pre-multiply to account for the alpha weighting */
  1573. if (alpha != frac_1) {
  1574. #ifdef PREMULTIPLY_TOWARDS_WHITE
  1575. frac alpha_bias = frac_1 - alpha;
  1576. #else
  1577. frac alpha_bias = 0;
  1578. #endif
  1579. for (i = 0; i < ncomps; i++)
  1580. cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias;
  1581. }
  1582. for (i = 0; i < ncomps; i++)
  1583. cv[i] = frac2cv(cm_comps[i]);
  1584. /* encode as a color index */
  1585. if (dev_proc(dev, map_rgb_alpha_color) != gx_default_map_rgb_alpha_color &&
  1586. (cv_alpha = frac2cv(alpha)) != gx_max_color_value)
  1587. color = dev_proc(dev, map_rgb_alpha_color)(dev, cv[0], cv[1], cv[2], cv_alpha);
  1588. else
  1589. color = dev_proc(dev, encode_color)(dev, cv);
  1590. /* check if the encoding was successful; we presume failure is rare */
  1591. if (color != gx_no_color_index)
  1592. color_set_pure(pdc, color);
  1593. }
  1594. private void
  1595. pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_imager_state * pis,
  1596. gx_device * dev, gs_color_select_t select)
  1597. {
  1598. int i, ncomps = dev->color_info.num_components;
  1599. bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
  1600. frac comp_value = all;
  1601. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1602. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1603. gx_color_index color;
  1604. if (pis->color_component_map.sep_type == SEP_ALL) {
  1605. /*
  1606. * Invert the photometric interpretation for additive
  1607. * color spaces because separations are always subtractive.
  1608. */
  1609. if (additive)
  1610. comp_value = frac_1 - comp_value;
  1611. /* Use the "all" value for all components */
  1612. i = pis->color_component_map.num_colorants - 1;
  1613. for (; i >= 0; i--)
  1614. cm_comps[i] = comp_value;
  1615. }
  1616. else {
  1617. /* map to the color model */
  1618. map_components_to_colorants(&comp_value, &(pis->color_component_map), cm_comps);
  1619. }
  1620. /* apply the transfer function(s); convert to color values */
  1621. if (additive)
  1622. for (i = 0; i < ncomps; i++)
  1623. cv[i] = frac2cv(gx_map_color_frac(pis,
  1624. cm_comps[i], effective_transfer[i]));
  1625. else
  1626. for (i = 0; i < ncomps; i++)
  1627. cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
  1628. (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
  1629. /* encode as a color index */
  1630. color = dev_proc(dev, encode_color)(dev, cv);
  1631. /* check if the encoding was successful; we presume failure is rare */
  1632. if (color != gx_no_color_index)
  1633. color_set_pure(pdc, color);
  1634. }
  1635. private void
  1636. pdf14_cmap_devicen_direct(const frac * pcc,
  1637. gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
  1638. gs_color_select_t select)
  1639. {
  1640. int i, ncomps = dev->color_info.num_components;
  1641. frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1642. gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
  1643. gx_color_index color;
  1644. /* map to the color model */
  1645. map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps);;
  1646. /* apply the transfer function(s); convert to color values */
  1647. if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
  1648. for (i = 0; i < ncomps; i++)
  1649. cv[i] = frac2cv(gx_map_color_frac(pis,
  1650. cm_comps[i], effective_transfer[i]));
  1651. else
  1652. for (i = 0; i < ncomps; i++)
  1653. cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
  1654. (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
  1655. /* encode as a color index */
  1656. color = dev_proc(dev, encode_color)(dev, cv);
  1657. /* check if the encoding was successful; we presume failure is rare */
  1658. if (color != gx_no_color_index)
  1659. color_set_pure(pdc, color);
  1660. }
  1661. private bool
  1662. pdf14_cmap_is_halftoned(const gs_imager_state * pis, gx_device * dev)
  1663. {
  1664. return false;
  1665. }
  1666. private const gx_color_map_procs *
  1667. pdf14_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev)
  1668. {
  1669. /* The pdf14 marking device itself is always continuous tone. */
  1670. return &pdf14_cmap_many;
  1671. }
  1672. int
  1673. gs_pdf14_device_push(gs_memory_t *mem, gs_imager_state * pis,
  1674. gx_device ** pdev, gx_device * target)
  1675. {
  1676. const pdf14_device * dev_proto;
  1677. pdf14_device *p14dev;
  1678. int code;
  1679. if_debug0('v', "[v]gs_pdf14_device_push\n");
  1680. code = get_pdf14_device_proto(target, &dev_proto);
  1681. if (code < 0)
  1682. return code;
  1683. code = gs_copydevice((gx_device **) &p14dev,
  1684. (const gx_device *) dev_proto, mem);
  1685. if (code < 0)
  1686. return code;
  1687. check_device_separable((gx_device *)p14dev);
  1688. gx_device_fill_in_procs((gx_device *)p14dev);
  1689. gs_pdf14_device_copy_params((gx_device *)p14dev, target);
  1690. rc_assign(p14dev->target, target, "gs_pdf14_device_push");
  1691. p14dev->save_get_cmap_procs = pis->get_cmap_procs;
  1692. pis->get_cmap_procs = pdf14_get_cmap_procs;
  1693. gx_set_cmap_procs(pis, (gx_device *)p14dev);
  1694. code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
  1695. *pdev = (gx_device *) p14dev;
  1696. pdf14_set_marking_params((gx_device *)p14dev, pis);
  1697. return code;
  1698. }
  1699. /*
  1700. * In a modest violation of good coding practice, the gs_composite_common
  1701. * fields are "known" to be simple (contain no pointers to garbage
  1702. * collected memory), and we also know the gs_pdf14trans_params_t structure
  1703. * to be simple, so we just create a trivial structure descriptor for the
  1704. * entire gs_pdf14trans_s structure.
  1705. */
  1706. #define private_st_gs_pdf14trans_t()\
  1707. gs_private_st_ptrs1(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
  1708. st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function)
  1709. /* GC descriptor for gs_pdf14trans_t */
  1710. private_st_gs_pdf14trans_t();
  1711. /*
  1712. * Check for equality of two PDF 1.4 transparency compositor objects.
  1713. *
  1714. * We are currently always indicating that PDF 1.4 transparency compositors are
  1715. * equal. Two transparency compositors may have teh same data but still
  1716. * represent separate actions. (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
  1717. * operations in a row mean that we are creating a group inside of a group.
  1718. */
  1719. private bool
  1720. c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
  1721. {
  1722. return false;
  1723. }
  1724. #ifdef DEBUG
  1725. static char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
  1726. #endif
  1727. #define put_value(dp, value)\
  1728. memcpy(dp, &value, sizeof(value));\
  1729. dp += sizeof(value)
  1730. /*
  1731. * Convert a PDF 1.4 transparency compositor to string form for use by the command
  1732. * list device.
  1733. */
  1734. private int
  1735. c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize)
  1736. {
  1737. const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
  1738. int need, avail = *psize;
  1739. /* Must be large enough for largest data struct */
  1740. byte buf[21 + sizeof(pparams->Background)
  1741. + sizeof(pparams->GrayBackground) + sizeof(pparams->bbox)];
  1742. byte * pbuf = buf;
  1743. int opcode = pparams->pdf14_op;
  1744. int mask_size = 0;
  1745. /* Write PDF 1.4 compositor data into the clist */
  1746. *pbuf++ = opcode; /* 1 byte */
  1747. switch (opcode) {
  1748. default: /* Should not occur. */
  1749. break;
  1750. case PDF14_PUSH_DEVICE:
  1751. case PDF14_POP_DEVICE:
  1752. case PDF14_END_TRANS_GROUP:
  1753. case PDF14_END_TRANS_MASK:
  1754. break; /* No data */
  1755. case PDF14_BEGIN_TRANS_GROUP:
  1756. /*
  1757. * The bbox data is floating point. We are not currently using it.
  1758. * So we are not currently putting it into the clist. We are also
  1759. * not using the color space.
  1760. */
  1761. *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
  1762. *pbuf++ = pparams->blend_mode;
  1763. put_value(pbuf, pparams->opacity.alpha);
  1764. put_value(pbuf, pparams->shape.alpha);
  1765. put_value(pbuf, pparams->bbox);
  1766. break;
  1767. case PDF14_INIT_TRANS_MASK:
  1768. *pbuf++ = pparams->csel;
  1769. break;
  1770. case PDF14_BEGIN_TRANS_MASK:
  1771. put_value(pbuf, pparams->subtype);
  1772. *pbuf++ = pparams->function_is_identity;
  1773. *pbuf++ = pparams->Background_components;
  1774. if (pparams->Background_components) {
  1775. const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
  1776. memcpy(pbuf, pparams->Background, l);
  1777. pbuf += l;
  1778. memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
  1779. pbuf += sizeof(pparams->GrayBackground);
  1780. }
  1781. if (!pparams->function_is_identity)
  1782. mask_size = sizeof(pparams->transfer_fn);
  1783. break;
  1784. case PDF14_SET_BLEND_PARAMS:
  1785. *pbuf++ = pparams->changed;
  1786. if (pparams->changed & PDF14_SET_BLEND_MODE)
  1787. *pbuf++ = pparams->blend_mode;
  1788. if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
  1789. *pbuf++ = pparams->text_knockout;
  1790. if (pparams->changed & PDF14_SET_OPACITY_ALPHA)
  1791. put_value(pbuf, pparams->opacity.alpha);
  1792. if (pparams->changed & PDF14_SET_SHAPE_ALPHA)
  1793. put_value(pbuf, pparams->shape.alpha);
  1794. break;
  1795. }
  1796. #undef put_value
  1797. /* check for fit */
  1798. need = (pbuf - buf) + mask_size;
  1799. *psize = need;
  1800. if (need > avail)
  1801. return_error(gs_error_rangecheck);
  1802. /* Copy our serialzed data into the output buffer */
  1803. memcpy(data, buf, need - mask_size);
  1804. if (mask_size) /* Include the transfer mask data if present */
  1805. memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
  1806. if_debug2('v', "[v] c_pdf14trans_write: opcode = %s need = %d\n",
  1807. pdf14_opcode_names[opcode], need);
  1808. return 0;
  1809. }
  1810. /* Function prototypes */
  1811. int gs_create_pdf14trans( gs_composite_t ** ppct,
  1812. const gs_pdf14trans_params_t * pparams,
  1813. gs_memory_t * mem );
  1814. #define read_value(dp, value)\
  1815. memcpy(&value, dp, sizeof(value));\
  1816. dp += sizeof(value)
  1817. /*
  1818. * Convert the string representation of the PDF 1.4 tranparency parameter
  1819. * into the full compositor.
  1820. */
  1821. private int
  1822. c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
  1823. uint size, gs_memory_t * mem )
  1824. {
  1825. gs_pdf14trans_params_t params = {0};
  1826. const byte * start = data;
  1827. int used, code = 0;
  1828. if (size < 1)
  1829. return_error(gs_error_rangecheck);
  1830. /* Read PDF 1.4 compositor data from the clist */
  1831. params.pdf14_op = *data++;
  1832. if_debug2('v', "[v] c_pdf14trans_read: opcode = %s avail = %d",
  1833. pdf14_opcode_names[params.pdf14_op], size);
  1834. switch (params.pdf14_op) {
  1835. default: /* Should not occur. */
  1836. break;
  1837. case PDF14_PUSH_DEVICE:
  1838. case PDF14_POP_DEVICE:
  1839. case PDF14_END_TRANS_GROUP:
  1840. break; /* No data */
  1841. case PDF14_BEGIN_TRANS_GROUP:
  1842. /*
  1843. * We are currently not using the bbox or the colorspace so they were
  1844. * not placed in the clist
  1845. */
  1846. params.Isolated = (*data) & 1;
  1847. params.Knockout = (*data++ >> 1) & 1;
  1848. params.blend_mode = *data++;
  1849. read_value(data, params.opacity.alpha);
  1850. read_value(data, params.shape.alpha);
  1851. read_value(data, params.bbox);
  1852. break;
  1853. case PDF14_INIT_TRANS_MASK:
  1854. params.csel = *data++;
  1855. break;
  1856. case PDF14_BEGIN_TRANS_MASK:
  1857. read_value(data, params.subtype);
  1858. params.function_is_identity = *data++;
  1859. params.Background_components = *data++;
  1860. if (params.Background_components) {
  1861. const int l = sizeof(params.Background[0]) * params.Background_components;
  1862. memcpy(params.Background, data, l);
  1863. data += l;
  1864. memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
  1865. data += sizeof(params.GrayBackground);
  1866. }
  1867. if (params.function_is_identity) {
  1868. int i;
  1869. for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
  1870. params.transfer_fn[i] = (byte)floor(i *
  1871. (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
  1872. }
  1873. } else {
  1874. read_value(data, params.transfer_fn);
  1875. }
  1876. break;
  1877. case PDF14_END_TRANS_MASK:
  1878. break; /* No data */
  1879. case PDF14_SET_BLEND_PARAMS:
  1880. params.changed = *data++;
  1881. if (params.changed & PDF14_SET_BLEND_MODE)
  1882. params.blend_mode = *data++;
  1883. if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
  1884. params.text_knockout = *data++;
  1885. if (params.changed & PDF14_SET_OPACITY_ALPHA)
  1886. read_value(data, params.opacity.alpha);
  1887. if (params.changed & PDF14_SET_SHAPE_ALPHA)
  1888. read_value(data, params.shape.alpha);
  1889. break;
  1890. }
  1891. code = gs_create_pdf14trans(ppct, &params, mem);
  1892. if (code < 0)
  1893. return code;
  1894. used = data - start;
  1895. if_debug1('v', " used = %d\n", used);
  1896. return used;
  1897. }
  1898. /*
  1899. * Create a PDF 1.4 transparency compositor.
  1900. *
  1901. * Note that this routine will be called only if the device is not already
  1902. * a PDF 1.4 transparency compositor.
  1903. */
  1904. private int
  1905. c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
  1906. gx_device ** pp14dev, gx_device * tdev, gs_imager_state * pis,
  1907. gs_memory_t * mem)
  1908. {
  1909. const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
  1910. gx_device * p14dev = NULL;
  1911. int code = 0;
  1912. /*
  1913. * We only handle the push operation. All other operations are ignored.
  1914. */
  1915. switch (pdf14pct->params.pdf14_op) {
  1916. case PDF14_PUSH_DEVICE:
  1917. code = gs_pdf14_device_push(mem, pis, &p14dev, tdev);
  1918. *pp14dev = p14dev;
  1919. break;
  1920. default:
  1921. *pp14dev = tdev;
  1922. break;
  1923. }
  1924. return code;
  1925. }
  1926. private composite_clist_write_update(c_pdf14trans_clist_write_update);
  1927. private composite_clist_read_update(c_pdf14trans_clist_read_update);
  1928. /*
  1929. * Methods for the PDF 1.4 transparency compositor
  1930. *
  1931. * Note: We have two set of methods. They are the same except for the
  1932. * composite_clist_write_update method. Once the clist write device is created,
  1933. * we use the second set of procedures. This prevents the creation of multiple
  1934. * PDF 1.4 clist write compositor devices being chained together.
  1935. */
  1936. const gs_composite_type_t gs_composite_pdf14trans_type = {
  1937. GX_COMPOSITOR_PDF14_TRANS,
  1938. {
  1939. c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
  1940. c_pdf14trans_equal, /* procs.equal */
  1941. c_pdf14trans_write, /* procs.write */
  1942. c_pdf14trans_read, /* procs.read */
  1943. /* Create a PDF 1.4 clist write device */
  1944. c_pdf14trans_clist_write_update, /* procs.composite_clist_write_update */
  1945. c_pdf14trans_clist_read_update /* procs.composite_clist_reade_update */
  1946. } /* procs */
  1947. };
  1948. const gs_composite_type_t gs_composite_pdf14trans_no_clist_writer_type = {
  1949. GX_COMPOSITOR_PDF14_TRANS,
  1950. {
  1951. c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
  1952. c_pdf14trans_equal, /* procs.equal */
  1953. c_pdf14trans_write, /* procs.write */
  1954. c_pdf14trans_read, /* procs.read */
  1955. /* The PDF 1.4 clist writer already exists, Do not create it. */
  1956. gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
  1957. c_pdf14trans_clist_read_update /* procs.composite_clist_reade_update */
  1958. } /* procs */
  1959. };
  1960. /*
  1961. * Verify that a compositor data structure is for the PDF 1.4 compositor.
  1962. */
  1963. int
  1964. gs_is_pdf14trans_compositor(const gs_composite_t * pct)
  1965. {
  1966. return (pct->type == &gs_composite_pdf14trans_type
  1967. || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
  1968. }
  1969. /*
  1970. * Create a PDF 1.4 transparency compositor data structure.
  1971. */
  1972. int
  1973. gs_create_pdf14trans(
  1974. gs_composite_t ** ppct,
  1975. const gs_pdf14trans_params_t * pparams,
  1976. gs_memory_t * mem )
  1977. {
  1978. gs_pdf14trans_t * pct;
  1979. rc_alloc_struct_0( pct,
  1980. gs_pdf14trans_t,
  1981. &st_pdf14trans,
  1982. mem,
  1983. return_error(gs_error_VMerror),
  1984. "gs_create_pdf14trans" );
  1985. pct->type = &gs_composite_pdf14trans_type;
  1986. pct->id = gs_next_ids(mem, 1);
  1987. pct->params = *pparams;
  1988. *ppct = (gs_composite_t *)pct;
  1989. return 0;
  1990. }
  1991. /*
  1992. * Send a PDF 1.4 transparency compositor action to the specified device.
  1993. */
  1994. int
  1995. send_pdf14trans(gs_imager_state * pis, gx_device * dev,
  1996. gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
  1997. {
  1998. gs_composite_t * pct = NULL;
  1999. int code;
  2000. code = gs_create_pdf14trans(&pct, pparams, mem);
  2001. if (code < 0)
  2002. return code;
  2003. code = dev_proc(dev, create_compositor) (dev, pcdev, pct, pis, mem);
  2004. gs_free_object(pis->memory, pct, "send_pdf14trans");
  2005. return code;
  2006. }
  2007. /* ------------- PDF 1.4 transparency device for clist writing ------------- */
  2008. /*
  2009. * The PDF 1.4 transparency compositor device may have a different process
  2010. * color model than the output device. If we are banding then we need to
  2011. * create two compositor devices. The output side (clist reader) needs a
  2012. * compositor to actually composite the output. We also need a compositor
  2013. * device before the clist writer. This is needed to provide a process color
  2014. * model which matches the PDF 1.4 blending space.
  2015. *
  2016. * This section provides support for this device.
  2017. */
  2018. /* Define the default alpha-compositing device. */
  2019. typedef struct pdf14_clist_device_s {
  2020. gx_device_forward_common;
  2021. const gx_color_map_procs *(*save_get_cmap_procs)(const gs_imager_state *,
  2022. const gx_device *);
  2023. gx_device_color_info saved_target_color_info;
  2024. float opacity;
  2025. float shape;
  2026. gs_blend_mode_t blend_mode;
  2027. bool text_knockout;
  2028. } pdf14_clist_device;
  2029. gs_private_st_suffix_add0_final(st_pdf14_clist_device,
  2030. pdf14_clist_device, "pdf14_clist_device",
  2031. device_c_pdf14_clist_enum_ptrs, device_c_pdf14_clist_reloc_ptrs,
  2032. gx_device_finalize, st_device_forward);
  2033. #define pdf14_clist_procs(get_color_mapping_procs, get_color_comp_index,\
  2034. encode_color, decode_color) \
  2035. {\
  2036. NULL, /* open */\
  2037. gx_forward_get_initial_matrix, /* get_initial_matrix */\
  2038. gx_forward_sync_output, /* sync_output */\
  2039. gx_forward_output_page, /* output_page */\
  2040. gx_forward_close_device, /* close_device */\
  2041. encode_color, /* rgb_map_rgb_color */\
  2042. decode_color, /* map_color_rgb */\
  2043. gx_forward_fill_rectangle, /* fill_rectangle */\
  2044. gx_forward_tile_rectangle, /* tile_rectangle */\
  2045. gx_forward_copy_mono, /* copy_mono */\
  2046. gx_forward_copy_color, /* copy_color */\
  2047. NULL , /* draw_line - obsolete */\
  2048. gx_forward_get_bits, /* get_bits */\
  2049. gx_forward_get_params, /* get_params */\
  2050. pdf14_put_params, /* put_params */\
  2051. encode_color, /* map_cmyk_color */\
  2052. gx_forward_get_xfont_procs, /* get_xfont_procs */\
  2053. gx_forward_get_xfont_device, /* get_xfont_device */\
  2054. NULL, /* map_rgb_alpha_color */\
  2055. gx_forward_get_page_device, /* get_page_device */\
  2056. gx_forward_get_alpha_bits, /* get_alpha_bits */\
  2057. NULL, /* copy_alpha */\
  2058. gx_forward_get_band, /* get_band */\
  2059. gx_forward_copy_rop, /* copy_rop */\
  2060. pdf14_clist_fill_path, /* fill_path */\
  2061. pdf14_clist_stroke_path, /* stroke_path */\
  2062. gx_forward_fill_mask, /* fill_mask */\
  2063. gx_forward_fill_trapezoid, /* fill_trapezoid */\
  2064. gx_forward_fill_parallelogram, /* fill_parallelogram */\
  2065. gx_forward_fill_triangle, /* fill_triangle */\
  2066. gx_forward_draw_thin_line, /* draw_thin_line */\
  2067. pdf14_clist_begin_image, /* begin_image */\
  2068. gx_forward_image_data, /* image_data */\
  2069. gx_forward_end_image, /* end_image */\
  2070. gx_forward_strip_tile_rectangle, /* strip_tile_rectangle */\
  2071. gx_forward_strip_copy_rop, /* strip_copy_rop, */\
  2072. gx_forward_get_clipping_box, /* get_clipping_box */\
  2073. pdf14_clist_begin_typed_image, /* begin_typed_image */\
  2074. gx_forward_get_bits_rectangle, /* get_bits_rectangle */\
  2075. NULL, /* map_color_rgb_alpha */\
  2076. pdf14_clist_create_compositor, /* create_compositor */\
  2077. gx_forward_get_hardware_params, /* get_hardware_params */\
  2078. pdf14_clist_text_begin, /* text_begin */\
  2079. NULL, /* finish_copydevice */\
  2080. pdf14_begin_transparency_group,\
  2081. pdf14_end_transparency_group,\
  2082. pdf14_begin_transparency_mask,\
  2083. pdf14_end_transparency_mask,\
  2084. NULL, /* discard_transparency_layer */\
  2085. get_color_mapping_procs, /* get_color_mapping_procs */\
  2086. get_color_comp_index, /* get_color_comp_index */\
  2087. encode_color, /* encode_color */\
  2088. decode_color /* decode_color */\
  2089. }
  2090. private dev_proc_create_compositor(pdf14_clist_create_compositor);
  2091. private dev_proc_create_compositor(pdf14_clist_forward_create_compositor);
  2092. private dev_proc_fill_path(pdf14_clist_fill_path);
  2093. private dev_proc_stroke_path(pdf14_clist_stroke_path);
  2094. private dev_proc_text_begin(pdf14_clist_text_begin);
  2095. private dev_proc_begin_image(pdf14_clist_begin_image);
  2096. private dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
  2097. private const gx_device_procs pdf14_clist_Gray_procs =
  2098. pdf14_clist_procs(gx_default_DevGray_get_color_mapping_procs,
  2099. gx_default_DevGray_get_color_comp_index,
  2100. gx_default_8bit_map_gray_color,
  2101. gx_default_8bit_map_color_gray);
  2102. private const gx_device_procs pdf14_clist_RGB_procs =
  2103. pdf14_clist_procs(gx_default_DevRGB_get_color_mapping_procs,
  2104. gx_default_DevRGB_get_color_comp_index,
  2105. gx_default_rgb_map_rgb_color,
  2106. gx_default_rgb_map_color_rgb);
  2107. private const gx_device_procs pdf14_clist_CMYK_procs =
  2108. pdf14_clist_procs(gx_default_DevCMYK_get_color_mapping_procs,
  2109. gx_default_DevCMYK_get_color_comp_index,
  2110. cmyk_8bit_map_cmyk_color, cmyk_8bit_map_color_cmyk);
  2111. const pdf14_clist_device pdf14_clist_Gray_device = {
  2112. std_device_color_stype_body(pdf14_clist_device, &pdf14_clist_Gray_procs,
  2113. "pdf14clistgray", &st_pdf14_clist_device,
  2114. XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
  2115. { 0 }
  2116. };
  2117. const pdf14_clist_device pdf14_clist_RGB_device = {
  2118. std_device_color_stype_body(pdf14_clist_device, &pdf14_clist_RGB_procs,
  2119. "pdf14clistRGB", &st_pdf14_clist_device,
  2120. XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
  2121. { 0 }
  2122. };
  2123. const pdf14_clist_device pdf14_clist_CMYK_device = {
  2124. std_device_std_color_full_body_type(pdf14_clist_device,
  2125. &pdf14_clist_CMYK_procs, "PDF14clistcmyk",
  2126. &st_pdf14_clist_device, XSIZE, YSIZE, X_DPI, Y_DPI, 32,
  2127. 0, 0, 0, 0, 0, 0),
  2128. { 0 }
  2129. };
  2130. /*
  2131. * the PDF 1.4 transparency spec says that color space for blending
  2132. * operations can be based upon either a color space specified in the
  2133. * group or a default value based upon the output device. We are
  2134. * currently only using a color space based upon the device.
  2135. */
  2136. private int
  2137. get_pdf14_clist_device_proto(gx_device * dev,
  2138. const pdf14_clist_device ** pdevproto)
  2139. {
  2140. pdf14_default_colorspace_t dev_cs =
  2141. pdf14_determine_default_blend_cs(dev);
  2142. switch (dev_cs) {
  2143. case DeviceGray:
  2144. *pdevproto = &pdf14_clist_Gray_device;
  2145. break;
  2146. case DeviceRGB:
  2147. *pdevproto = &pdf14_clist_RGB_device;
  2148. break;
  2149. case DeviceCMYK:
  2150. *pdevproto = &pdf14_clist_CMYK_device;
  2151. break;
  2152. default: /* Should not occur */
  2153. return_error(gs_error_rangecheck);
  2154. }
  2155. return 0;
  2156. }
  2157. private int
  2158. pdf14_create_clist_device(gs_memory_t *mem, gs_imager_state * pis,
  2159. gx_device ** ppdev, gx_device * target)
  2160. {
  2161. const pdf14_clist_device * dev_proto;
  2162. pdf14_clist_device *pdev;
  2163. int code;
  2164. if_debug0('v', "[v]pdf14_create_clist_device\n");
  2165. code = get_pdf14_clist_device_proto(target, &dev_proto);
  2166. if (code < 0)
  2167. return code;
  2168. code = gs_copydevice((gx_device **) &pdev,
  2169. (const gx_device *) dev_proto, mem);
  2170. if (code < 0)
  2171. return code;
  2172. check_device_separable((gx_device *)pdev);
  2173. gx_device_fill_in_procs((gx_device *)pdev);
  2174. gs_pdf14_device_copy_params((gx_device *)pdev, target);
  2175. rc_assign(pdev->target, target, "pdf14_create_clist_device");
  2176. code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
  2177. *ppdev = (gx_device *) pdev;
  2178. return code;
  2179. }
  2180. /*
  2181. * Disable the PDF 1.4 clist compositor device. Once created, the PDF 1.4
  2182. * compositor device is never removed. (We do not have a remove compositor
  2183. * method.) However it is no-op'ed when the PDF 1.4 device is popped. This
  2184. * routine implements that action.
  2185. */
  2186. private int
  2187. pdf14_disable_clist_device(gs_memory_t *mem, gs_imager_state * pis,
  2188. gx_device * dev)
  2189. {
  2190. gx_device_forward * pdev = (gx_device_forward *)dev;
  2191. gx_device * target = pdev->target;
  2192. if_debug0('v', "[v]pdf14_disable_clist_device\n");
  2193. /*
  2194. * To disable the action of this device, we forward all device
  2195. * procedures to the target except the create_compositor and copy
  2196. * the target's color_info.
  2197. */
  2198. dev->color_info = target->color_info;
  2199. pdf14_forward_device_procs(dev);
  2200. set_dev_proc(dev, create_compositor, pdf14_clist_forward_create_compositor);
  2201. return 0;
  2202. }
  2203. /*
  2204. * Recreate the PDF 1.4 clist compositor device. Once created, the PDF 1.4
  2205. * compositor device is never removed. (We do not have a remove compositor
  2206. * method.) However it is no-op'ed when the PDF 1.4 device is popped. This
  2207. * routine will re-enable the compositor if the PDF 1.4 device is pushed
  2208. * again.
  2209. */
  2210. private int
  2211. pdf14_recreate_clist_device(gs_memory_t *mem, gs_imager_state * pis,
  2212. gx_device * dev)
  2213. {
  2214. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2215. gx_device * target = pdev->target;
  2216. const pdf14_clist_device * dev_proto;
  2217. int code;
  2218. if_debug0('v', "[v]pdf14_recreate_clist_device\n");
  2219. /*
  2220. * We will not use the entire prototype device but we will set the
  2221. * color related info to match the prototype.
  2222. */
  2223. code = get_pdf14_clist_device_proto(target, &dev_proto);
  2224. if (code < 0)
  2225. return code;
  2226. pdev->color_info = dev_proto->color_info;
  2227. pdev->procs = dev_proto->procs;
  2228. gx_device_fill_in_procs(dev);
  2229. check_device_separable((gx_device *)pdev);
  2230. return code;
  2231. }
  2232. /*
  2233. * When we are banding, we have two PDF 1.4 compositor devices. One for
  2234. * when we are creating the clist. The second is for imaging the data from
  2235. * the clist. This routine is part of the clist writing PDF 1.4 device.
  2236. * This routine is only called once the PDF 1.4 clist write compositor already
  2237. * exists.
  2238. */
  2239. private int
  2240. pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev,
  2241. const gs_composite_t * pct, gs_imager_state * pis, gs_memory_t * mem)
  2242. {
  2243. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2244. int code;
  2245. /* We only handle a few PDF 1.4 transparency operations 4 */
  2246. if (gs_is_pdf14trans_compositor(pct)) {
  2247. const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
  2248. switch (pdf14pct->params.pdf14_op) {
  2249. case PDF14_PUSH_DEVICE:
  2250. /* Re-activate the PDF 1.4 compositor */
  2251. pdev->saved_target_color_info = pdev->target->color_info;
  2252. pdev->target->color_info = pdev->color_info;
  2253. pdev->save_get_cmap_procs = pis->get_cmap_procs;
  2254. pis->get_cmap_procs = pdf14_get_cmap_procs;
  2255. gx_set_cmap_procs(pis, dev);
  2256. code = pdf14_recreate_clist_device(mem, pis, dev);
  2257. pdev->blend_mode = pdev->text_knockout = 0;
  2258. pdev->opacity = pdev->shape = 0.0;
  2259. if (code < 0)
  2260. return code;
  2261. /*
  2262. * This routine is part of the PDF 1.4 clist write device.
  2263. * Change the compositor procs to not create another since we
  2264. * do not need to create a chain of identical devices.
  2265. */
  2266. {
  2267. gs_composite_t pctemp = *pct;
  2268. pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
  2269. code = dev_proc(pdev->target, create_compositor)
  2270. (pdev->target, pcdev, &pctemp, pis, mem);
  2271. *pcdev = dev;
  2272. return code;
  2273. }
  2274. case PDF14_POP_DEVICE:
  2275. /* Restore the color_info for the clist device */
  2276. pdev->target->color_info = pdev->saved_target_color_info;
  2277. pis->get_cmap_procs = pdev->save_get_cmap_procs;
  2278. gx_set_cmap_procs(pis, pdev->target);
  2279. /* Disable the PDF 1.4 compositor */
  2280. pdf14_disable_clist_device(mem, pis, dev);
  2281. /*
  2282. * Make sure that the transfer funtions, etc. are current.
  2283. */
  2284. code = cmd_put_color_mapping(
  2285. (gx_device_clist_writer *)(pdev->target), pis);
  2286. if (code < 0)
  2287. return code;
  2288. break;
  2289. case PDF14_BEGIN_TRANS_GROUP:
  2290. /*
  2291. * Keep track of any changes made in the blending parameters.
  2292. */
  2293. pdev->text_knockout = pdf14pct->params.Knockout;
  2294. pdev->blend_mode = pdf14pct->params.blend_mode;
  2295. pdev->opacity = pdf14pct->params.opacity.alpha;
  2296. pdev->shape = pdf14pct->params.shape.alpha;
  2297. {
  2298. const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
  2299. if (pparams->Background_components != 0 &&
  2300. pparams->Background_components != pdev->color_info.num_components)
  2301. return_error(gs_error_rangecheck);
  2302. }
  2303. break;
  2304. default:
  2305. break; /* Pass remaining ops to target */
  2306. }
  2307. }
  2308. code = dev_proc(pdev->target, create_compositor)
  2309. (pdev->target, pcdev, pct, pis, mem);
  2310. if (*pcdev != pdev->target)
  2311. rc_assign(pdev->target, *pcdev, "pdf14_clist_create_compositor");
  2312. *pcdev = dev;
  2313. return code;
  2314. }
  2315. /*
  2316. * The PDF 1.4 clist compositor is never removed. (We do not have a 'remove
  2317. * compositor' method. However the compositor is disabled when we are not
  2318. * doing a page which uses PDF 1.4 transparency. This routine is only active
  2319. * when the PDF 1.4 compositor is 'disabled'. It checks for reenabling the
  2320. * PDF 1.4 compositor. Otherwise it simply passes create compositor requests
  2321. * to the targer.
  2322. */
  2323. private int
  2324. pdf14_clist_forward_create_compositor(gx_device * dev, gx_device * * pcdev,
  2325. const gs_composite_t * pct, gs_imager_state * pis,
  2326. gs_memory_t * mem)
  2327. {
  2328. pdf14_device *pdev = (pdf14_device *)dev;
  2329. gx_device * tdev = pdev->target;
  2330. gx_device * ndev;
  2331. int code = 0;
  2332. *pcdev = dev;
  2333. if (gs_is_pdf14trans_compositor(pct)) {
  2334. const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
  2335. if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
  2336. return pdf14_clist_create_compositor(dev, &ndev, pct, pis, mem);
  2337. return 0;
  2338. }
  2339. code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pis, mem);
  2340. if (code < 0)
  2341. return code;
  2342. pdev->target = ndev;
  2343. return 0;
  2344. }
  2345. /*
  2346. * If any of the PDF 1.4 transparency blending parameters have changed, we
  2347. * need to send them to the PDF 1.4 compositor on the output side of the clist.
  2348. */
  2349. private int
  2350. pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_imager_state * pis)
  2351. {
  2352. gs_pdf14trans_params_t params = { 0 };
  2353. gx_device * pcdev;
  2354. int changed = 0;
  2355. int code = 0;
  2356. params.pdf14_op = PDF14_SET_BLEND_PARAMS;
  2357. if (pis->blend_mode != pdev->blend_mode) {
  2358. changed |= PDF14_SET_BLEND_MODE;
  2359. params.blend_mode = pdev->blend_mode = pis->blend_mode;
  2360. }
  2361. if (pis->text_knockout != pdev->text_knockout) {
  2362. changed |= PDF14_SET_TEXT_KNOCKOUT;
  2363. params.text_knockout = pdev->text_knockout = pis->text_knockout;
  2364. }
  2365. if (pis->shape.alpha != pdev->shape) {
  2366. changed |= PDF14_SET_SHAPE_ALPHA;
  2367. params.shape.alpha = pdev->shape = pis->shape.alpha;
  2368. }
  2369. if (pis->opacity.alpha != pdev->opacity) {
  2370. changed |= PDF14_SET_OPACITY_ALPHA;
  2371. params.opacity.alpha = pdev->opacity = pis->opacity.alpha;
  2372. }
  2373. /*
  2374. * Put parameters into a compositor parameter and then call the
  2375. * create_compositor. This will pass the data through the clist
  2376. * to the PDF 1.4 transparency output device. Note: This action
  2377. * never creates a new PDF 1.4 compositor and it does not change
  2378. * the imager state.
  2379. */
  2380. if (changed != 0) {
  2381. params.changed = changed;
  2382. code = send_pdf14trans((gs_imager_state *)pis, (gx_device *)pdev,
  2383. &pcdev, &params, pis->memory);
  2384. }
  2385. return code;
  2386. }
  2387. /*
  2388. * fill_path routine for the PDF 1.4 transaprency compositor device for
  2389. * writing the clist.
  2390. */
  2391. private int
  2392. pdf14_clist_fill_path(gx_device *dev, const gs_imager_state *pis,
  2393. gx_path *ppath, const gx_fill_params *params,
  2394. const gx_drawing_color *pdcolor,
  2395. const gx_clip_path *pcpath)
  2396. {
  2397. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2398. gs_imager_state new_is = *pis;
  2399. int code;
  2400. /*
  2401. * Ensure that that the PDF 1.4 reading compositor will have the current
  2402. * blending parameters. This is needed since the fill_rectangle routines
  2403. * do not have access to the imager state. Thus we have to pass any
  2404. * changes explictly.
  2405. */
  2406. code = pdf14_clist_update_params(pdev, pis);
  2407. if (code < 0)
  2408. return code;
  2409. /*
  2410. * The blend operations are not idempotent. Force non-idempotent
  2411. * filling and stroking operations.
  2412. */
  2413. new_is.log_op |= lop_pdf14;
  2414. return gx_default_fill_path(dev, &new_is, ppath, params, pdcolor, pcpath);
  2415. }
  2416. /*
  2417. * stroke_path routine for the PDF 1.4 transaprency compositor device for
  2418. * writing the clist.
  2419. */
  2420. private int
  2421. pdf14_clist_stroke_path(gx_device *dev, const gs_imager_state *pis,
  2422. gx_path *ppath, const gx_stroke_params *params,
  2423. const gx_drawing_color *pdcolor,
  2424. const gx_clip_path *pcpath)
  2425. {
  2426. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2427. gs_imager_state new_is = *pis;
  2428. int code;
  2429. /*
  2430. * Ensure that that the PDF 1.4 reading compositor will have the current
  2431. * blending parameters. This is needed since the fill_rectangle routines
  2432. * do not have access to the imager state. Thus we have to pass any
  2433. * changes explictly.
  2434. */
  2435. code = pdf14_clist_update_params(pdev, pis);
  2436. if (code < 0)
  2437. return code;
  2438. /*
  2439. * The blend operations are not idempotent. Force non-idempotent
  2440. * filling and stroking operations.
  2441. */
  2442. new_is.log_op |= lop_pdf14;
  2443. return gx_default_stroke_path(dev, &new_is, ppath, params, pdcolor, pcpath);
  2444. }
  2445. /*
  2446. * text_begin routine for the PDF 1.4 transaprency compositor device for
  2447. * writing the clist.
  2448. */
  2449. private int
  2450. pdf14_clist_text_begin(gx_device * dev, gs_imager_state * pis,
  2451. const gs_text_params_t * text, gs_font * font,
  2452. gx_path * path, const gx_device_color * pdcolor,
  2453. const gx_clip_path * pcpath, gs_memory_t * memory,
  2454. gs_text_enum_t ** ppenum)
  2455. {
  2456. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2457. gs_text_enum_t *penum;
  2458. int code;
  2459. /*
  2460. * Ensure that that the PDF 1.4 reading compositor will have the current
  2461. * blending parameters. This is needed since the fill_rectangle routines
  2462. * do not have access to the imager state. Thus we have to pass any
  2463. * changes explictly.
  2464. */
  2465. code = pdf14_clist_update_params(pdev, pis);
  2466. if (code < 0)
  2467. return code;
  2468. /* Pass text_begin to the target */
  2469. code = gx_default_text_begin(dev, pis, text, font, path,
  2470. pdcolor, pcpath, memory, &penum);
  2471. if (code < 0)
  2472. return code;
  2473. *ppenum = (gs_text_enum_t *)penum;
  2474. return code;
  2475. }
  2476. private int
  2477. pdf14_clist_begin_image(gx_device * dev,
  2478. const gs_imager_state * pis, const gs_image_t * pim,
  2479. gs_image_format_t format, const gs_int_rect * prect,
  2480. const gx_drawing_color * pdcolor,
  2481. const gx_clip_path * pcpath,
  2482. gs_memory_t * memory, gx_image_enum_common_t ** pinfo)
  2483. {
  2484. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2485. int code;
  2486. /*
  2487. * Ensure that that the PDF 1.4 reading compositor will have the current
  2488. * blending parameters. This is needed since the fill_rectangle routines
  2489. * do not have access to the imager state. Thus we have to pass any
  2490. * changes explictly.
  2491. */
  2492. code = pdf14_clist_update_params(pdev, pis);
  2493. if (code < 0)
  2494. return code;
  2495. /* Pass image to the target */
  2496. return gx_default_begin_image(dev, pis, pim, format, prect,
  2497. pdcolor, pcpath, memory, pinfo);
  2498. }
  2499. private int
  2500. pdf14_clist_begin_typed_image(gx_device * dev, const gs_imager_state * pis,
  2501. const gs_matrix *pmat, const gs_image_common_t *pic,
  2502. const gs_int_rect * prect,
  2503. const gx_drawing_color * pdcolor,
  2504. const gx_clip_path * pcpath, gs_memory_t * mem,
  2505. gx_image_enum_common_t ** pinfo)
  2506. {
  2507. pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
  2508. int code;
  2509. /*
  2510. * Ensure that that the PDF 1.4 reading compositor will have the current
  2511. * blending parameters. This is needed since the fill_rectangle routines
  2512. * do not have access to the imager state. Thus we have to pass any
  2513. * changes explictly.
  2514. */
  2515. code = pdf14_clist_update_params(pdev, pis);
  2516. if (code < 0)
  2517. return code;
  2518. /* Pass image to the target */
  2519. return gx_default_begin_typed_image(dev, pis, pmat,
  2520. pic, prect, pdcolor, pcpath, mem, pinfo);
  2521. }
  2522. /*
  2523. * When we push a PDF 1.4 transparency compositor onto the clist, we also need
  2524. * to create a compositing device for clist writing. The primary purpose of
  2525. * this device is to provide support for the process color model in which
  2526. * the PDF 1.4 transparency is done. (This may differ from the process color
  2527. * model of the output device.) The actual work of compositing the image is
  2528. * done on the output (reader) side of the clist.
  2529. */
  2530. private int
  2531. c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
  2532. gx_device ** pcdev, gs_imager_state * pis, gs_memory_t * mem)
  2533. {
  2534. const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
  2535. pdf14_clist_device * p14dev;
  2536. int code = 0;
  2537. /* We only handle the push/pop operations */
  2538. switch (pdf14pct->params.pdf14_op) {
  2539. case PDF14_PUSH_DEVICE:
  2540. code = pdf14_create_clist_device(mem, pis, pcdev, dev);
  2541. /*
  2542. * Set the color_info of the clist device to match the compositing
  2543. * device. We will restore it when the compositor is popped.
  2544. * See pdf14_clist_create_compositor for the restore. Do the same
  2545. * with the imager state's get_cmap_procs. We do not want the
  2546. * imager state to use transfer functions on our color values. The
  2547. * transfer functions will be applied at the end after we have done
  2548. * our PDF 1.4 blend operations.
  2549. */
  2550. p14dev = (pdf14_clist_device *)(*pcdev);
  2551. p14dev->saved_target_color_info = dev->color_info;
  2552. dev->color_info = (*pcdev)->color_info;
  2553. p14dev->save_get_cmap_procs = pis->get_cmap_procs;
  2554. pis->get_cmap_procs = pdf14_get_cmap_procs;
  2555. gx_set_cmap_procs(pis, dev);
  2556. return code;
  2557. case PDF14_POP_DEVICE:
  2558. /*
  2559. * Ensure that the tranfer functions, etc. are current before we
  2560. * dump our transparency image to the output device.
  2561. */
  2562. code = cmd_put_halftone((gx_device_clist_writer *)
  2563. (((pdf14_clist_device *)dev)->target), pis->dev_ht);
  2564. break;
  2565. default:
  2566. break; /* do nothing for remaining ops */
  2567. }
  2568. *pcdev = dev;
  2569. return code;
  2570. }
  2571. /*
  2572. * When we push a PDF 1.4 transparency compositor, we need to make the clist
  2573. * device color_info data match the compositing device. We need to do this
  2574. * since the PDF 1.4 transparency compositing device may use a different
  2575. * process color model than the output device. We do not need to modify the
  2576. * color related device procs since the compositing device has its own. We
  2577. * restore the color_info data when the transparency device is popped.
  2578. */
  2579. private int
  2580. c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
  2581. gx_device * tdev, gs_imager_state * pis, gs_memory_t * mem)
  2582. {
  2583. pdf14_device * p14dev = (pdf14_device *)tdev;
  2584. gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
  2585. /*
  2586. * We only handle the push/pop operations. Save and restore the color_info
  2587. * field for the clist device. (This is needed since the process color
  2588. * model of the clist device needs to match the PDF 1.4 compositing
  2589. * device.
  2590. */
  2591. switch (pdf14pct->params.pdf14_op) {
  2592. case PDF14_PUSH_DEVICE:
  2593. p14dev->saved_clist_color_info = cdev->color_info;
  2594. cdev->color_info = p14dev->color_info;
  2595. break;
  2596. case PDF14_POP_DEVICE:
  2597. cdev->color_info = p14dev->saved_clist_color_info;
  2598. break;
  2599. default:
  2600. break; /* do nothing for remaining ops */
  2601. }
  2602. return 0;
  2603. }