From c40db67210e981537efdd33d8445c29f16e4f491 Mon Sep 17 00:00:00 2001 From: Michael Vrhel Date: Wed, 3 Nov 2021 19:57:15 -0700 Subject: Fix for setting of PageSpotColors Bug 704660 plmain.c should not be setting the PageSpotColors value. This should be set by the individual interpreters on a per page basis. This change fixes a crash (Bug 704660) reduces the number of closing and opening times of the device with pdfi and pdfi renders more than 4 spots to the separation devices just fine. Also for gpdl with HEAD, the subsequent execution of a PS file following a PCL file did not properly reset the PageSpotColors to -1 as is required for PS files, resulting in improper output when going to a separation device. This commit includes a fix for that. Tested with command line gpdl -sDEVICE=psdcmyk -r72 -o ./myoutputs/pdl_input_%d.psd ./myinputs/owl.pcl ./myinputs/Ad_InDesign.ps ./myinputs/spots_multi_page.pdf ./myinputs/input.xps ./myinputs/deviceNImage.eps ./myinputs/DeviceN_20Colors.pdf ./myinputs/page_spots/Ad_InDesign.ps to verify that the number of spots was getting properly set with each interpreter and page (when applicable) change. --- gpdl/psitop.c | 25 +++++++++++++++++++++++++ pcl/pcl/pcjob.c | 3 +++ pcl/pl/plmain.c | 13 ------------- pcl/pxl/pxsessio.c | 8 ++++++++ pdf/pdf_device.c | 28 ---------------------------- xps/xpspage.c | 13 ++++++++++++- 6 files changed, 48 insertions(+), 42 deletions(-) diff --git a/gpdl/psitop.c b/gpdl/psitop.c index 00cf1a1a3..367599abc 100644 --- a/gpdl/psitop.c +++ b/gpdl/psitop.c @@ -420,6 +420,31 @@ ps_impl_init_job(pl_interp_implementation_t *impl, (void)code1; } + /* Make sure the PageSpotColors is set to -1 for PS */ + { + gs_c_param_list* params; + int page_spot_colors = -1; + int code2; + + params = gs_c_param_list_alloc(psi->memory, "ps_impl_init_job"); + if (params == NULL) + return_error(gs_error_VMerror); + + gs_c_param_list_write(params, psi->memory); + gs_param_list_set_persistent_keys((gs_param_list*)params, false); + + code2 = param_write_int((gs_param_list*)params, "PageSpotColors", &(page_spot_colors)); + if (code2 < 0) + return code2; + + gs_c_param_list_read(params); + + code2 = psapi_set_device_param(psi->psapi_instance, (gs_param_list*)params); + if (code2 < 0) + return code2; + + gs_c_param_list_release(params); + } return code; } diff --git a/pcl/pcl/pcjob.c b/pcl/pcl/pcjob.c index cf3f02ac5..da3e20249 100644 --- a/pcl/pcl/pcjob.c +++ b/pcl/pcl/pcjob.c @@ -367,6 +367,9 @@ pcjob_do_reset(pcl_state_t * pcs, pcl_reset_type_t type) code = put_param1_bool(pcs, "BindShortEdge", pcs->bind_short_edge); if (code < 0) return code; + code = put_param1_int(pcs, "PageSpotColors", 0); + if (code < 0) + return code; } if (type & (pcl_reset_initial ^ pcl_reset_cold)) diff --git a/pcl/pl/plmain.c b/pcl/pl/plmain.c index 71108c0e8..ae33903a8 100644 --- a/pcl/pl/plmain.c +++ b/pcl/pl/plmain.c @@ -2780,19 +2780,6 @@ help: arg = NULL; } out: - /* PCL does not support spot colors and XPS files with spot colors are very - rare (as in never found in the wild). Handling XPS spots for a separation - device will require a little work. To avoid issues at the current time, - we will do the following - */ - { - int num_spots = 0; - gs_c_param_list_write_more(params); - code = param_write_int((gs_param_list *)params, "PageSpotColors", &(num_spots)); - if (code < 0) - return code; - } - /* Do any last minute language specific device initialisation * (i.e. let gs_init.ps do its worst). */ code = pl_main_post_args_init(pmi); diff --git a/pcl/pxl/pxsessio.c b/pcl/pxl/pxsessio.c index ea00634f5..82b17f766 100644 --- a/pcl/pxl/pxsessio.c +++ b/pcl/pxl/pxsessio.c @@ -457,6 +457,7 @@ pxBeginPage(px_args_t * par, px_state_t * pxs) int iv; bool bv; int ecode = 0; + int page_spot_colors = 0; fa.data = fv; fa.persistent = false; @@ -468,6 +469,13 @@ pxBeginPage(px_args_t * par, px_state_t * pxs) if (ecode < 0) return ecode; + /* PXL never has spot colors on the page */ + gs_c_param_list_write(&list, mem); + ecode = param_write_int(plist, "PageSpotColors", &(page_spot_colors)); + ecode = px_put1(dev, &list, ecode); + if (ecode < 0) + return ecode; + gs_c_param_list_write(&list, mem); fv[0] = pxs->media_dims.x; fv[1] = pxs->media_dims.y; diff --git a/pdf/pdf_device.c b/pdf/pdf_device.c index d77a07199..9ed971332 100644 --- a/pdf/pdf_device.c +++ b/pdf/pdf_device.c @@ -138,34 +138,6 @@ void pdfi_device_set_flags(pdf_context *ctx) /* See if it is a DeviceN (spot capable) */ ctx->device_state.spot_capable = dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0); - /* This code is fankly icky and deserves to be changed. The problem it solves is that the - * PL interpreter code layer specifically sets "PageSpotColours" to 0 (none) in plmain.c - * pl_main_process_options(). Once that has been done, there is no simple way to - * process more than 4 spot channels. I thought at first we could use pl_main_post_args_init() - * but that doesn't get access to the main instance (where the params are stored) or to the - * params directly so it is unable to change them. - * So the only solution is either to remove the code which sets the PageSpotColours to 0, or - * to close the device, set the PageSpotColours to -1 (unknown) and re-open the device. - * That's what we do here. This means we end up closing and re-opening the device a lot, - * I'd like to avoid that so : - * FIXME: only do this once, ideally only call pdfi_device_set_flags once - */ - if (ctx->device_state.spot_capable && dev->is_open) { - gs_c_param_list params; - int num_spots = -1; - - gs_closedevice(dev); - - gs_c_param_list_write(¶ms, ctx->memory); - (void)param_write_int((gs_param_list *)¶ms, "PageSpotColors", &(num_spots)); - gs_c_param_list_read(¶ms); - (void)gs_putdeviceparams(ctx->pgs->device, (gs_param_list *)¶ms); - gs_c_param_list_release(¶ms); - - (void)gs_setdevice_no_erase(ctx->pgs, ctx->pgs->device); - gs_erasepage(ctx->pgs); - } - /* If multi-page output, can't do certain pdfmarks */ if (ctx->device_state.writepdfmarks) { if (gx_outputfile_is_separate_pages(((gx_device_vector *)dev)->fname, dev->memory)) { diff --git a/xps/xpspage.c b/xps/xpspage.c index dafd76ed5..6237b7a33 100644 --- a/xps/xpspage.c +++ b/xps/xpspage.c @@ -125,6 +125,7 @@ xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part) char base_uri[1024]; char *s; int code, code1, code2; + int page_spot_colors = 0; if_debug1m('|', ctx->memory, "doc: parsing page %s\n", part->name); @@ -205,9 +206,19 @@ xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part) } } + /* At some point we may want to add the pre-parse for named colors and n-channel + colors here. The XPS spec makes it optional to put the colorant names in the + ICC profile. So we would need some sort of fall back and we would need to know + if a name color that we encounter is one that we already encountered, which would get + very messy in terms of comparing ICC profiles. Especially for example, if + the same spot color was used individually AND in an n-channel color profile. + Since XPS usage is rare, and the demand for support of real spot color separation + non-existent, we will set the PageSpotColors to 0 at this point. */ + + code = param_write_int((gs_param_list *)&list, "PageSpotColors", &(page_spot_colors)); code1 = param_write_bool((gs_param_list *)&list, "PageUsesTransparency", &(ctx->has_transparency)); code2 = param_write_float_array((gs_param_list *)&list, ".MediaSize", &fa); - if ( code1 >= 0 || code2 >= 0) + if ( code >= 0 || code1 >= 0 || code2 >= 0) { gs_c_param_list_read(&list); code = gs_putdeviceparams(dev, (gs_param_list *)&list); -- cgit v1.2.1