summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2019-11-05 15:12:35 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2020-01-10 09:37:24 -0800
commit4c8d80f91aef717877f36699fbf0bae6a568494c (patch)
tree2a48eb66bb780a98057aa0b1e1ce0bda4fae035b
parentcf101811c2921850fbe24a44693aceaead7b67ca (diff)
downloadghostpdl-4c8d80f91aef717877f36699fbf0bae6a568494c.tar.gz
Add a way to set the op device state (fill or stroke) through the compositor
This command will only occur when we are doing an actual operation (e.g. fill stroke)
-rw-r--r--base/gscdevn.c1
-rw-r--r--base/gscsepr.c1
-rw-r--r--base/gscspace.c3
-rw-r--r--base/gsovrc.c62
-rw-r--r--base/gsovrc.h9
-rw-r--r--base/gstext.c19
6 files changed, 69 insertions, 26 deletions
diff --git a/base/gscdevn.c b/base/gscdevn.c
index f40bf2c93..6e0e0f269 100644
--- a/base/gscdevn.c
+++ b/base/gscdevn.c
@@ -752,6 +752,7 @@ gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_gstate * pgs)
/* Only DeviceCMYK can use overprint mode */
pgs->color[0].effective_opm = 0;
+ params.op_state = OP_STATE_NONE;
return gs_gstate_update_overprint(pgs, &params);
}
}
diff --git a/base/gscsepr.c b/base/gscsepr.c
index 83f10c811..09317e4c9 100644
--- a/base/gscsepr.c
+++ b/base/gscsepr.c
@@ -195,6 +195,7 @@ gx_set_overprint_Separation(const gs_color_space * pcs, gs_gstate * pgs)
pcs->params.separation.sep_type != SEP_ALL;
params.is_fill_color = pgs->is_fill_color;
params.drawn_comps = 0;
+ params.op_state = OP_STATE_NONE;
if (params.retain_any_comps) {
if (pcs->params.separation.sep_type != SEP_NONE) {
int mcomp = pcmap->color_map[0];
diff --git a/base/gscspace.c b/base/gscspace.c
index 2d5583f17..8e4f51422 100644
--- a/base/gscspace.c
+++ b/base/gscspace.c
@@ -476,6 +476,7 @@ gx_set_no_overprint(gs_gstate* pgs)
gs_overprint_params_t params = { 0 };
params.retain_any_comps = false;
+ params.op_state = OP_STATE_NONE;
params.is_fill_color = pgs->is_fill_color;
pgs->color[0].effective_opm = 0;
@@ -501,6 +502,7 @@ gx_spot_colors_set_overprint(const gs_color_space * pcs, gs_gstate * pgs)
params.retain_any_comps = true;
params.is_fill_color = pgs->is_fill_color;
+ params.op_state = OP_STATE_NONE;
/* Only DeviceCMYK case can have overprint mode set to true */
pgs->color[0].effective_opm = 0;
@@ -746,6 +748,7 @@ int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs)
params.is_fill_color = pgs->is_fill_color;
params.retain_any_comps = true;
params.drawn_comps = drawn_comps;
+ params.op_state = OP_STATE_NONE;
if_debug2m(gs_debug_flag_overprint, pgs->memory,
"[overprint] gx_set_overprint_cmyk. retain_any_comps = %d, drawn_comps = 0x%x\n",
diff --git a/base/gsovrc.c b/base/gsovrc.c
index d1e814476..58e1ee671 100644
--- a/base/gsovrc.c
+++ b/base/gsovrc.c
@@ -109,6 +109,7 @@ c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
pparams0 = &((const gs_overprint_t *)(pct0))->params;
pparams1 = &((const gs_overprint_t *)(pct1))->params;
+
if (pparams0->is_fill_color != pparams1->is_fill_color)
return true; /* this changed */
if (!pparams0->retain_any_comps)
@@ -124,8 +125,8 @@ c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
* representation of an overprint compositor.
*/
#define OVERPRINT_ANY_COMPS 1
-#define OVERPRINT_SPOT_COMPS 2
-#define OVERPRINT_IS_FILL_COLOR 4
+#define OVERPRINT_IS_FILL_COLOR 2
+#define OVERPRINT_SET_FILL_COLOR 0xc
/*
* Convert an overprint compositor to string form for use by the command
@@ -139,9 +140,11 @@ c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_devi
int used = 1, avail = *psize;
/* encoded the booleans in a single byte */
- if (pparams->retain_any_comps || pparams->is_fill_color) {
+ if (pparams->retain_any_comps || pparams->is_fill_color || pparams->op_state) {
flags |= (pparams->retain_any_comps) ? OVERPRINT_ANY_COMPS : 0;
flags |= (pparams->is_fill_color) ? OVERPRINT_IS_FILL_COLOR : 0;
+ flags |= (pparams->op_state) ? OVERPRINT_SET_FILL_COLOR : 0;
+
/* write out the component bits */
if (pparams->retain_any_comps) {
uint tmp_size = (avail > 0 ? avail - 1 : 0);
@@ -186,6 +189,7 @@ c_overprint_read(
if_debug1m('v', mem, "[v]c_overprint_read(%d)", flags);
params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0;
params.is_fill_color = (flags & OVERPRINT_IS_FILL_COLOR) != 0;
+ params.op_state = (flags & OVERPRINT_SET_FILL_COLOR) != 0;
params.idle = 0;
params.drawn_comps = 0;
@@ -197,6 +201,8 @@ c_overprint_read(
nbytes += code;
if_debug0m('v', mem, ", drawn_comps read");
}
+ if_debug1m('v', mem, ", retain_any_comps=%d", params.retain_any_comps);
+ if_debug1m('v', mem, ", is_fill_color=%d", params.is_fill_color);
if_debug1m('v', mem, ", drawn_comps=0x%x", params.drawn_comps);
if_debug0m('v', mem, "\n");
code = gs_create_overprint(ppct, &params, mem);
@@ -294,7 +300,7 @@ typedef struct overprint_device_s {
* target color space is not separable and linear. It is also used
* for the devn color values since we may need more than 8 components
*/
- bool is_fill_color; /* used to select drawn_comps, fill or stroke */
+ OP_FS_STATE op_state; /* used to select drawn_comps, fill or stroke */
gx_color_index drawn_comps_fill;
gx_color_index drawn_comps_stroke; /* pparams->is_fill_color determines which to set */
bool retain_none_stroke; /* These are used to know when we can set the procs to forward */
@@ -755,6 +761,12 @@ update_overprint_params(
we will turn it off when setting one and turn on
when setting the other (or vice versa) */
+ /* Note if pparams is to set the opdev fill stroke state. Do that now and exit */
+ if (pparams->op_state != OP_STATE_NONE) {
+ opdev->op_state = pparams->op_state;
+ return 0;
+ }
+
if_debug4m(gs_debug_flag_overprint, opdev->memory,
"[overprint] update_overprint_params enter. retain_any_comps = %d, idle = %d, drawn_comps = 0x%x, is_fill_color = %d\n",
pparams->retain_any_comps, pparams->idle, pparams->drawn_comps, pparams->is_fill_color);
@@ -927,9 +939,9 @@ overprint_create_compositor(
params.idle = pct->idle;
/* device must already exist, so just update the parameters if settings change */
- if_debug7m(gs_debug_flag_overprint, opdev->memory,
- "[overprint] overprint_create_compositor test for change. params.idle = %d vs. opdev->is_idle = %d \n params.is_fill_color = %d vs. opdev->is_fill_color = %d \n params.drawn_comps = 0x%x vs. opdev->drawn_comps_fill = 0x%x OR opdev->drawn_comps_stroke = 0x%x\n",
- params.idle, opdev->is_idle, params.is_fill_color, opdev->is_fill_color, params.drawn_comps, opdev->drawn_comps_fill, opdev->drawn_comps_stroke);
+ if_debug6m(gs_debug_flag_overprint, opdev->memory,
+ "[overprint] overprint_create_compositor test for change. params.idle = %d vs. opdev->is_idle = %d \n params.is_fill_color = %d: params.drawn_comps = 0x%x vs. opdev->drawn_comps_fill = 0x%x OR opdev->drawn_comps_stroke = 0x%x\n",
+ params.idle, opdev->is_idle, params.is_fill_color, params.drawn_comps, opdev->drawn_comps_fill, opdev->drawn_comps_stroke);
if (!params.retain_any_comps || params.idle != opdev->is_idle ||
params.drawn_comps != (params.is_fill_color ?
@@ -967,12 +979,12 @@ overprint_generic_fill_rectangle(
/* See if we even need to do any overprinting. We have to maintain
the compositor active for fill/stroke cases even if we are only
doing a fill or a stroke */
- if ((opdev->is_fill_color && opdev->retain_none_fill) ||
- (!opdev->is_fill_color && opdev->retain_none_stroke))
+ if ((opdev->op_state == OP_STATE_FILL && opdev->retain_none_fill) ||
+ (opdev->op_state == OP_STATE_STROKE && opdev->retain_none_stroke))
return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, width, height, color);
return gx_overprint_generic_fill_rectangle(tdev,
- opdev->is_fill_color ?
+ opdev->op_state == OP_STATE_FILL ?
opdev->drawn_comps_fill : opdev->drawn_comps_stroke,
x, y, width, height, color, dev->memory);
}
@@ -1020,7 +1032,7 @@ overprint_copy_planes(gx_device * dev, const byte * data, int data_x, int raster
uchar num_comps;
uchar k,j;
gs_memory_t * mem = dev->memory;
- gx_color_index comps = opdev->is_fill_color ? opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
+ gx_color_index comps = opdev->op_state == OP_STATE_FILL ? opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
byte *curr_data = (byte *) data + data_x;
int row, offset;
@@ -1144,8 +1156,8 @@ overprint_fill_rectangle_hl_color(gx_device *dev,
/* See if we even need to do any overprinting. We have to maintain
the compositor active for fill/stroke cases even if we are only
doing a fill or a stroke */
- if ((opdev->is_fill_color && opdev->retain_none_fill) ||
- (!opdev->is_fill_color && opdev->retain_none_stroke))
+ if ((opdev->op_state == OP_STATE_FILL && opdev->retain_none_fill) ||
+ (opdev->op_state == OP_STATE_STROKE && opdev->retain_none_stroke))
return (*dev_proc(tdev, fill_rectangle_hl_color)) (tdev, rect, pgs, pdcolor, pcpath);
depth = tdev->color_info.depth;
@@ -1188,7 +1200,7 @@ overprint_fill_rectangle_hl_color(gx_device *dev,
while (h-- > 0 && code >= 0) {
gb_rect.p.y = y++;
gb_rect.q.y = y;
- comps = opdev->is_fill_color ? opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
+ comps = opdev->op_state == OP_STATE_FILL ? opdev->drawn_comps_fill : opdev->drawn_comps_stroke;
/* And now through each plane */
for (k = 0; k < tdev->color_info.num_components; k++) {
/* First set the params to zero for all planes except the one we want */
@@ -1245,8 +1257,8 @@ overprint_sep_fill_rectangle(
/* See if we even need to do any overprinting. We have to maintain
the compositor active for fill/stroke cases even if we are only
doing a fill or a stroke */
- if ((opdev->is_fill_color && opdev->retain_none_fill) ||
- (!opdev->is_fill_color && opdev->retain_none_stroke))
+ if ((opdev->op_state == OP_STATE_FILL && opdev->retain_none_fill) ||
+ (opdev->op_state == OP_STATE_STROKE && opdev->retain_none_stroke))
return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, width, height, color);
/*
@@ -1274,12 +1286,12 @@ overprint_sep_fill_rectangle(
* depth < 8 * sizeof(mono_fill_chunk).
*/
if ( depth <= 8 * sizeof(mono_fill_chunk) && (depth & (depth - 1)) == 0)
- return gx_overprint_sep_fill_rectangle_1(tdev, opdev->is_fill_color ?
+ return gx_overprint_sep_fill_rectangle_1(tdev, opdev->op_state == OP_STATE_FILL ?
opdev->retain_mask_fill : opdev->retain_mask_stroke,
x, y, width, height,
color, dev->memory);
else
- return gx_overprint_sep_fill_rectangle_2(tdev, opdev->is_fill_color ?
+ return gx_overprint_sep_fill_rectangle_2(tdev, opdev->op_state == OP_STATE_FILL ?
opdev->retain_mask_fill : opdev->retain_mask_stroke,
x, y, width, height,
color, dev->memory);
@@ -1294,7 +1306,7 @@ overprint_fill_path(gx_device* pdev, const gs_gstate* pgs,
{
overprint_device_t* opdev = (overprint_device_t*)pdev;
- opdev->is_fill_color = true;
+ opdev->op_state = OP_STATE_FILL;
return gx_default_fill_path(pdev, pgs, ppath, params_fill,
pdcolor, pcpath);
}
@@ -1308,7 +1320,7 @@ overprint_stroke_path(gx_device* pdev, const gs_gstate* pgs,
overprint_device_t* opdev = (overprint_device_t*)pdev;
int code;
- opdev->is_fill_color = false;
+ opdev->op_state = OP_STATE_STROKE;
/* Stroke methods use fill path so set that to default to
avoid mix up of is_fill_color */
@@ -1335,14 +1347,14 @@ overprint_fill_stroke_path(gx_device * pdev, const gs_gstate * pgs,
int code;
overprint_device_t *opdev = (overprint_device_t *)pdev;
- opdev->is_fill_color = true;
+ opdev->op_state = OP_STATE_FILL;
code = dev_proc(pdev, fill_path)(pdev, pgs, ppath, params_fill, pdevc_fill, pcpath);
if (code < 0)
return code;
+
/* Set up for stroke */
- opdev->is_fill_color = false;
+ opdev->op_state = OP_STATE_STROKE;
code = dev_proc(pdev, stroke_path)(pdev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
- opdev->is_fill_color = true;
return code;
}
@@ -1357,9 +1369,9 @@ overprint_text_begin(gx_device* dev, gs_gstate* pgs,
overprint_device_t* opdev = (overprint_device_t*)dev;
if (pgs->text_rendering_mode == 0)
- opdev->is_fill_color = true;
+ opdev->op_state = OP_STATE_FILL;
else if (pgs->text_rendering_mode == 1)
- opdev->is_fill_color = false;
+ opdev->op_state = OP_STATE_STROKE;
return gx_default_text_begin(dev, pgs, text, font,
path, pdcolor, pcpath, mem, ppte);
diff --git a/base/gsovrc.h b/base/gsovrc.h
index 22822b1b1..48ce148e9 100644
--- a/base/gsovrc.h
+++ b/base/gsovrc.h
@@ -216,6 +216,12 @@
* closing of a device is not itself used as an error indication.
*/
+typedef enum {
+ OP_STATE_NONE = 0,
+ OP_STATE_FILL,
+ OP_STATE_STROKE,
+} OP_FS_STATE;
+
typedef struct gs_overprint_params_s gs_overprint_params_t;
struct gs_overprint_params_s {
@@ -248,7 +254,8 @@ struct gs_overprint_params_s {
* it is to be left unaffected.
*/
gx_color_index drawn_comps;
- bool is_fill_color; /* for fill_stroke_path we differentiate */
+ bool is_fill_color; /* This tells us what the current color is for our set up */
+ OP_FS_STATE op_state; /* This sets the state of the device for an upcoming command */
};
/*
diff --git a/base/gstext.c b/base/gstext.c
index 1296e64f4..bb8b08e9c 100644
--- a/base/gstext.c
+++ b/base/gstext.c
@@ -271,6 +271,7 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text,
{
gx_clip_path *pcpath = 0;
int code;
+ gs_overprint_params_t op_params = { 0 };
/*
* Detect nocurrentpoint now, even if the string is empty, for Adobe
@@ -310,6 +311,24 @@ gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text,
code = gs_gstate_color_load(pgs);
if (code < 0)
return code;
+
+ /* If overprint is true, push the compositor action to set the op device state */
+ if (pgs->overprint || pgs->stroke_overprint) {
+ gx_device* dev = pgs->device;
+ cmm_dev_profile_t* dev_profile;
+
+ dev_proc(dev, get_profile)(dev, &dev_profile);
+ if (dev_profile->sim_overprint && dev_profile->device_profile[0]->data_cs == gsCMYK) {
+ if (pgs->overprint && (pgs->text_rendering_mode == 0)) {
+ op_params.op_state = OP_STATE_FILL;
+ gs_gstate_update_overprint(pgs, &op_params);
+ } else if (pgs->stroke_overprint && (pgs->text_rendering_mode == 1)) {
+ op_params.op_state = OP_STATE_STROKE;
+ gs_gstate_update_overprint(pgs, &op_params);
+ }
+ }
+ }
+
pgs->device->sgr.stroke_stored = false;
return gx_device_text_begin(pgs->device, pgs,
text, pgs->font, pgs->path,