From 7086f246fa047bcb9f3e9cfaacfbdae709058b91 Mon Sep 17 00:00:00 2001 From: Ken Sharp Date: Fri, 26 Apr 2013 12:57:40 +0100 Subject: Allow devices to inform the PCL interpreter that it must not alter palettes Bug #692786 "Problem with HPGL paletted colour" pdfwrite (and potentially other devices) can't cope with situations where the interpreter alters the 'palette' (the lookup table in a /Indexed space) after the space has been set to be the current color space. However, if we unilaterally preserve the palette, it seems that this causes performance problems (see bug #692786. Here we add a new special op 'needs_invariant_palette' which allows a device to communicate this. We alter the PCL interpreter to inquire the device's requirements, and aler pdfwrite to communicate its needs. This results in > 300 differences with pdfwrite, all of them progressions --- gs/base/gdevdflt.c | 1 + gs/base/gxdevsop.h | 8 ++++++++ gs/devices/vector/gdevpdfi.c | 5 +++++ pcl/pcpalet.c | 7 +++++++ 4 files changed, 21 insertions(+) diff --git a/gs/base/gdevdflt.c b/gs/base/gdevdflt.c index 057264b14..375580ce6 100644 --- a/gs/base/gdevdflt.c +++ b/gs/base/gdevdflt.c @@ -929,6 +929,7 @@ gx_default_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) case gxdso_is_native_planar: case gxdso_supports_devn: case gxdso_supports_hlcolor: + case gxdso_needs_invariant_palette: return 0; case gxdso_pattern_shfill_doesnt_need_path: return (pdev->procs.fill_path == gx_default_fill_path); diff --git a/gs/base/gxdevsop.h b/gs/base/gxdevsop.h index 61249b91a..da198a767 100644 --- a/gs/base/gxdevsop.h +++ b/gs/base/gxdevsop.h @@ -253,6 +253,14 @@ enum { * Return 0 for 'no special treatment', or 1 for the anitdropout * downscaler. */ gxdso_interpolate_antidropout, + /* gxdso_needs_invariant_palette: + * The PCL interpreter can set a /Indexed coluor space, and then + * alter the palette afterwards. For rendering the paletter lookup + * is done as required, so this works, but for high level devices + * (eg pdfwrite) we can't deal with this. return '0' if the device + * doesn't care if the palette changes, and 1 if it does. + */ + gxdso_needs_invariant_palette, /* Add new gxdso_ keys above this. */ gxdso_pattern__LAST }; diff --git a/gs/devices/vector/gdevpdfi.c b/gs/devices/vector/gdevpdfi.c index 5b16c6ad2..3e022c9a5 100644 --- a/gs/devices/vector/gdevpdfi.c +++ b/gs/devices/vector/gdevpdfi.c @@ -2530,6 +2530,11 @@ gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size) which is actually a devn vs. the pattern type for pdfwrite. We use this to distingush between the two */ return 1; + case gxdso_needs_invariant_palette: + /* Indicates that it is not permissible to change /Indexed colour space + * palette entries after the colour space has been set. + */ + return 1; } return gx_default_dev_spec_op(pdev1, dev_spec_op, data, size); } diff --git a/pcl/pcpalet.c b/pcl/pcpalet.c index 571d28f71..9a0066522 100644 --- a/pcl/pcpalet.c +++ b/pcl/pcpalet.c @@ -27,6 +27,7 @@ #include "gxcmap.h" #include "gxdcconv.h" #include "gzstate.h" +#include "gxdevsop.h" /* for special ops */ /* RC routines */ gs_private_st_simple(st_palette_t, pcl_palette_t, "pcl palette object"); @@ -448,6 +449,12 @@ pcl_palette_set_color(pcl_state_t * pcs, int indx, const float comps[3] code = pcl_cs_indexed_set_palette_entry(&(pcs->ppalet->pindexed), indx, comps); + /* Check if the device requires that the palette must not change */ + if (dev_proc(pcs->pgs->device, dev_spec_op)(pcs->pgs->device, + gxdso_needs_invariant_palette, 0, 0)) + /* change the ID if so to indicate a difdferent colour space */ + pcs->ppalet->pindexed->pcspace->id = gs_next_ids(pcs->memory, 1); + if (pcs->monochrome_mode == 0) { was_gray = pcs->ppalet->pht->is_gray_render_method; -- cgit v1.2.1