[gs-cvs] rev 8585 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Mon Mar 3 08:01:13 PST 2008
Author: leonardo
Date: 2008-03-03 08:01:12 -0800 (Mon, 03 Mar 2008)
New Revision: 8585
Modified:
trunk/gs/src/gdevdflt.c
trunk/gs/src/gdevp14.c
trunk/gs/src/gdevp14.h
trunk/gs/src/gsalphac.c
trunk/gs/src/gsovrc.c
trunk/gs/src/gstparam.h
trunk/gs/src/gstrans.c
trunk/gs/src/gstrans.h
trunk/gs/src/gxclimag.c
trunk/gs/src/gxclist.c
trunk/gs/src/gxclist.h
trunk/gs/src/gxclpath.c
trunk/gs/src/gxclrast.c
trunk/gs/src/gxcomp.h
Log:
Fix (clist) : Crop transparencsy commands while clist writing, step 2.
DETAILS :
This is a preparation to the next step.
The patch introduces a transparency stack for clist writer,
which saves cropping when entering a transparency group,
and restores when exiting it. The cropping is being narrowed
with transparency group's bounding box.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gdevdflt.c
===================================================================
--- trunk/gs/src/gdevdflt.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gdevdflt.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -881,7 +881,16 @@
return 0; /* Do nothing */
}
+/*
+ * Default handler for get_cropping returns no cropping.
+ */
int
+gx_default_composite_get_cropping(const gs_composite_t *pxcte, int *ry, int *rheight)
+{
+ return 0; /* No cropping. */
+}
+
+int
gx_default_finish_copydevice(gx_device *dev, const gx_device *from_dev)
{
/* Only allow copying the prototype. */
Modified: trunk/gs/src/gdevp14.c
===================================================================
--- trunk/gs/src/gdevp14.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gdevp14.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -545,6 +545,7 @@
result->transfer_fn = NULL;
result->maskbuf = NULL;
result->idle = idle;
+ result->mask_id = 0;
if (height <= 0 || idle) {
/* Empty clipping - will skip all drawings. */
@@ -647,7 +648,8 @@
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect,
bool isolated, bool knockout,
byte alpha, byte shape,
- gs_blend_mode_t blend_mode, bool idle)
+ gs_blend_mode_t blend_mode, bool idle,
+ uint mask_id)
{
pdf14_buf *tos = ctx->stack;
pdf14_buf *buf, *backdrop;
@@ -674,6 +676,7 @@
buf->alpha = alpha;
buf->shape = shape;
buf->blend_mode = blend_mode;
+ buf->mask_id = mask_id;
buf->maskbuf = ctx->maskbuf; /* Save becasuse the group rendering may set up
another (nested) mask. */
@@ -739,11 +742,21 @@
int x1 = min(tos->rect.q.x, nos->rect.q.x);
pdf14_buf *maskbuf = tos->maskbuf;
+ if (maskbuf != NULL && maskbuf->mask_id != tos->mask_id) {
+ /* We're under clist reader, and it skipped a group,
+ which is resetting maskbuf. Force freeing the mask.
+ */
+ ctx->maskbuf = maskbuf;
+ maskbuf = NULL;
+ }
if (ctx->maskbuf) {
/* Happens with the test case of bug 689492 with no banding
while rendering the group of an image with a mask.
Not sure why gs/lib processes a mask inside the image droup,
- anyway we need to release it safely. */
+ anyway we need to release it safely.
+
+ See also the comment above.
+ */
pdf14_buf_free(ctx->maskbuf, ctx->memory);
ctx->maskbuf = NULL;
}
@@ -895,7 +908,7 @@
# if VD_PAINT_COLORS
vd_pixel(int2fixed(x), int2fixed(y), n_chan == 1 ?
(nos_pixel[0] << 16) + (nos_pixel[0] << 8) + nos_pixel[0] :
- (nos_pixel[0] << 16) + (nos_pixel[1] << 8) + nos_pixel[2]);*/
+ (nos_pixel[0] << 16) + (nos_pixel[1] << 8) + nos_pixel[2]);
# endif
# if VD_PAINT_ALPHA
vd_pixel(int2fixed(x), int2fixed(y),
@@ -941,7 +954,8 @@
*/
static int
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, byte bg_alpha,
- byte *transfer_fn, bool idle, bool replacing)
+ byte *transfer_fn, bool idle, bool replacing,
+ uint mask_id)
{
pdf14_buf *buf;
@@ -972,6 +986,7 @@
buf->shape = 0xff;
buf->blend_mode = BLEND_MODE_Normal;
buf->transfer_fn = transfer_fn;
+ buf->mask_id = mask_id;
{ /* If replacing=false, we start the mask for an image with SMask.
In this case the image's SMask temporary replaces the
mask of the containing group.
@@ -1851,6 +1866,7 @@
pdf14_disable_device(gx_device * dev)
{
gx_device_forward * pdev = (gx_device_forward *)dev;
+ pdf14_device *cdev = (pdf14_device *)dev;
if_debug0('v', "[v]pdf14_disable_device\n");
dev->color_info = pdev->target->color_info;
@@ -2242,7 +2258,8 @@
}
static int
-pdf14_compute_group_device_int_rect(const gs_matrix *ctm, const gs_rect *pbbox, gs_int_rect *rect)
+pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
+ const gs_rect *pbbox, gs_int_rect *rect)
{
gs_rect dev_bbox;
int code;
@@ -2285,7 +2302,8 @@
ptgp->Isolated, ptgp->Knockout,
(byte)floor (255 * alpha + 0.5),
(byte)floor (255 * pis->shape.alpha + 0.5),
- pis->blend_mode, ptgp->idle);
+ pis->blend_mode, ptgp->idle,
+ ptgp->mask_id);
return code;
}
@@ -2326,7 +2344,8 @@
if_debug1('v', "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
memcpy(transfer_fn, ptmp->transfer_fn, size_of(ptmp->transfer_fn));
return pdf14_push_transparency_mask(pdev->ctx, &pdev->ctx->rect, bg_alpha,
- transfer_fn, ptmp->idle, ptmp->replacing);
+ transfer_fn, ptmp->idle, ptmp->replacing,
+ ptmp->mask_id);
}
static int
@@ -2844,25 +2863,29 @@
#endif
#define put_value(dp, value)\
- memcpy(dp, &value, sizeof(value));\
- dp += sizeof(value)
+ BEGIN\
+ memcpy(dp, &value, sizeof(value));\
+ dp += sizeof(value);\
+ END
/*
* Convert a PDF 1.4 transparency compositor to string form for use by the command
* list device.
*/
static int
-c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize)
+c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
{
const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
int need, avail = *psize;
/* Must be large enough for largest data struct */
byte buf[25 /* See sput_matrix. */ +
21 + sizeof(pparams->Background)
- + sizeof(pparams->GrayBackground) + sizeof(pparams->bbox)];
+ + sizeof(pparams->GrayBackground) + sizeof(pparams->bbox)
+ + sizeof(cdev->mask_id)];
byte * pbuf = buf;
int opcode = pparams->pdf14_op;
int mask_size = 0;
+ uint mask_id = 0;
int len, code;
/* Write PDF 1.4 compositor data into the clist */
@@ -2881,8 +2904,9 @@
put_value(pbuf, pparams->num_spot_colors);
break;
case PDF14_POP_DEVICE:
+ code = 0;
+ break;
case PDF14_END_TRANS_GROUP:
- case PDF14_END_TRANS_MASK:
break; /* No data */
case PDF14_BEGIN_TRANS_GROUP:
/*
@@ -2894,13 +2918,17 @@
*pbuf++ = pparams->blend_mode;
put_value(pbuf, pparams->opacity.alpha);
put_value(pbuf, pparams->shape.alpha);
- put_value(pbuf, pparams->bbox);
+ put_value(pbuf, pparams->bbox);
+ mask_id = pparams->mask_id;
+ put_value(pbuf, pparams->mask_id);
break;
case PDF14_BEGIN_TRANS_MASK:
put_value(pbuf, pparams->subtype);
*pbuf++ = pparams->replacing;
*pbuf++ = pparams->function_is_identity;
*pbuf++ = pparams->Background_components;
+ mask_id = pparams->mask_id;
+ put_value(pbuf, pparams->mask_id);
if (pparams->Background_components) {
const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
@@ -2912,6 +2940,8 @@
if (!pparams->function_is_identity)
mask_size = sizeof(pparams->transfer_fn);
break;
+ case PDF14_END_TRANS_MASK:
+ break;
case PDF14_SET_BLEND_PARAMS:
*pbuf++ = pparams->changed;
if (pparams->changed & PDF14_SET_BLEND_MODE)
@@ -2924,7 +2954,6 @@
put_value(pbuf, pparams->shape.alpha);
break;
}
-#undef put_value
/* check for fit */
need = (pbuf - buf) + mask_size;
@@ -2939,26 +2968,31 @@
/* If we are writing more than the maximum ever expected,
* return a rangecheck error.
*/
- if ( need > MAX_CLIST_COMPOSITOR_SIZE )
+ if ( need + 3 > MAX_CLIST_COMPOSITOR_SIZE )
return_error(gs_error_rangecheck);
/* Copy our serialzed data into the output buffer */
memcpy(data, buf, need - mask_size);
if (mask_size) /* Include the transfer mask data if present */
memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
- if_debug2('v', "[v] c_pdf14trans_write: opcode = %s need = %d\n",
- pdf14_opcode_names[opcode], need);
+ if_debug3('v', "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
+ pdf14_opcode_names[opcode], mask_id, need);
return 0;
}
+#undef put_value
+
+
/* Function prototypes */
static int gs_create_pdf14trans( gs_composite_t ** ppct,
const gs_pdf14trans_params_t * pparams,
gs_memory_t * mem );
#define read_value(dp, value)\
- memcpy(&value, dp, sizeof(value));\
- dp += sizeof(value)
+ BEGIN\
+ memcpy(&value, dp, sizeof(value));\
+ dp += sizeof(value);\
+ END
/*
* Convert the string representation of the PDF 1.4 transparency parameter
@@ -3003,6 +3037,7 @@
read_value(data, params.opacity.alpha);
read_value(data, params.shape.alpha);
read_value(data, params.bbox);
+ read_value(data, params.mask_id);
break;
case PDF14_BEGIN_TRANS_MASK:
/* This is the largest transparency parameter at this time (potentially
@@ -3021,6 +3056,7 @@
params.replacing = *data++;
params.function_is_identity = *data++;
params.Background_components = *data++;
+ read_value(data, params.mask_id);
if (params.Background_components) {
const int l = sizeof(params.Background[0]) * params.Background_components;
@@ -3041,8 +3077,7 @@
}
break;
case PDF14_END_TRANS_MASK:
- code += 0; /* A good place for a breakpoint. */
- break; /* No data */
+ break;
case PDF14_SET_BLEND_PARAMS:
params.changed = *data++;
if (params.changed & PDF14_SET_BLEND_MODE)
@@ -3059,11 +3094,11 @@
if (code < 0)
return code;
used = data - start;
- if_debug1('v', " used = %d\n", used);
+ if_debug2('v', " mask_id=%d used = %d\n", params.mask_id, used);
/* If we read more than the maximum expected, return a rangecheck error */
- if ( used > MAX_CLIST_COMPOSITOR_SIZE )
- return_error(gs_error_rangecheck);
+ if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
+ return_error(gs_error_rangecheck);
else
return used;
}
@@ -3256,6 +3291,7 @@
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
static composite_clist_write_update(c_pdf14trans_clist_write_update);
static composite_clist_read_update(c_pdf14trans_clist_read_update);
+static composite_get_cropping_proc(c_pdf14trans_get_cropping);
/*
@@ -3278,7 +3314,8 @@
c_pdf14trans_is_friendly, /* procs.is_friendly */
/* Create a PDF 1.4 clist write device */
c_pdf14trans_clist_write_update, /* procs.composite_clist_write_update */
- c_pdf14trans_clist_read_update /* procs.composite_clist_reade_update */
+ c_pdf14trans_clist_read_update, /* procs.composite_clist_reade_update */
+ c_pdf14trans_get_cropping /* procs.composite_get_cropping */
} /* procs */
};
@@ -3294,7 +3331,8 @@
c_pdf14trans_is_friendly, /* procs.is_friendly */
/* The PDF 1.4 clist writer already exists, Do not create it. */
gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
- c_pdf14trans_clist_read_update /* procs.composite_clist_reade_update */
+ c_pdf14trans_clist_read_update, /* procs.composite_clist_reade_update */
+ c_pdf14trans_get_cropping /* procs.composite_get_cropping */
} /* procs */
};
@@ -4159,13 +4197,9 @@
pdev->blend_mode = pdf14pct->params.blend_mode;
pdev->opacity = pdf14pct->params.opacity.alpha;
pdev->shape = pdf14pct->params.shape.alpha;
- {
- const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
-
- if (pparams->Background_components != 0 &&
- pparams->Background_components != pdev->color_info.num_components)
- return_error(gs_error_rangecheck);
- }
+ if (pdf14pct->params.Background_components != 0 &&
+ pdf14pct->params.Background_components != pdev->color_info.num_components)
+ return_error(gs_error_rangecheck);
break;
default:
break; /* Pass remaining ops to target */
@@ -4418,8 +4452,6 @@
pdf14_clist_device * p14dev;
int code = 0;
- state_update(ctm); /* See c_pdf14trans_write. */
-
/* We only handle the push/pop operations */
switch (pdf14pct->params.pdf14_op) {
case PDF14_PUSH_DEVICE:
@@ -4463,23 +4495,69 @@
code = clist_writer_check_empty_cropping_stack(cdev);
break;
case PDF14_BEGIN_TRANS_GROUP:
- { pdf14_device *pdev = (pdf14_device *)*pcdev;
- gs_int_rect rect;
+ { /* HACK: store mask_id into pparams for subsequent calls of c_pdf14trans_write. */
+ gs_pdf14trans_t * pdf14pct_nolconst = (gs_pdf14trans_t *) pcte; /* Break 'const'. */
- code = pdf14_compute_group_device_int_rect(&ctm_only(pis),
- &pdf14pct->params.bbox, &rect);
+ pdf14pct_nolconst->params.mask_id = (cdev->temp_mask_id != 0 ? cdev->temp_mask_id : cdev->mask_id);
+ if_debug2('v', "[v]c_pdf14trans_clist_write_update group mask_id=%d temp_mask_id=%d\n",
+ cdev->mask_id, cdev->temp_mask_id);
+ }
+ if (cdev->temp_mask_id)
+ cdev->temp_mask_id = 0;
+ else
+ cdev->mask_id = 0;
+ break;
+ case PDF14_END_TRANS_GROUP:
+ code = 0; /* A place for breakpoint. */
+ break;
+ case PDF14_BEGIN_TRANS_MASK:
+ { int save_mask_id = cdev->mask_id;
+ int save_temp_mask_id = cdev->temp_mask_id;
- if (code >= 0)
- code = clist_writer_push_cropping(cdev, rect.p.y, rect.q.y - rect.p.y);
+ if (!cdev->mask_id || pdf14pct->params.replacing)
+ cdev->mask_id = ++cdev->mask_id_count;
+ else
+ cdev->temp_mask_id = ++cdev->mask_id_count;
+ { /* HACK: store mask_id into pparams for subsequent calls of c_pdf14trans_write. */
+ gs_pdf14trans_t * pdf14pct_nolconst = (gs_pdf14trans_t *) pcte; /* Break 'const'. */
+
+ pdf14pct_nolconst->params.mask_id = (cdev->temp_mask_id != 0 ? cdev->temp_mask_id : cdev->mask_id);
+ if_debug2('v', "[v]c_pdf14trans_clist_write_update mask mask_id=%d temp_mask_id=%d\n",
+ cdev->mask_id, cdev->temp_mask_id);
+ }
+ code = clist_writer_push_no_cropping(cdev);
+ /* Delay updating current mask id until the mask is completed,
+ because the mask may have internal groups and masks.
+ clist_writer_pop_cropping will set up the currnt mask id. */
+ cdev->mask_id = save_mask_id;
+ cdev->temp_mask_id = save_temp_mask_id;
}
break;
- case PDF14_END_TRANS_GROUP:
+ case PDF14_END_TRANS_MASK:
code = clist_writer_pop_cropping(cdev);
break;
default:
break; /* do nothing for remaining ops */
}
*pcdev = dev;
+#if 0
+ state_update(ctm); /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, apply_create_compositor. */
+#elif 0
+ if (code < 0)
+ return code;
+ code = gs_setmatrix(&cdev->imager_state, &pdf14pct->params.ctm); /* See
+ c_pdf14trans_write, c_pdf14trans_adjust_ctm, apply_create_compositor. */
+#else
+ cdev->imager_state.ctm.xx = pdf14pct->params.ctm.xx;
+ cdev->imager_state.ctm.xy = pdf14pct->params.ctm.xy;
+ cdev->imager_state.ctm.yx = pdf14pct->params.ctm.yx;
+ cdev->imager_state.ctm.yy = pdf14pct->params.ctm.yy;
+ cdev->imager_state.ctm.tx = pdf14pct->params.ctm.tx;
+ cdev->imager_state.ctm.ty = pdf14pct->params.ctm.ty;
+ cdev->imager_state.ctm.tx_fixed = float2fixed(cdev->imager_state.ctm.tx);
+ cdev->imager_state.ctm.ty_fixed = float2fixed(cdev->imager_state.ctm.ty);
+#endif
+ cmd_clear_known(cdev, ctm_known); /* Wrote another ctm than from imager state. */
return code;
}
@@ -4565,6 +4643,33 @@
}
/*
+ * Get cropping for the compositor command.
+ */
+static int
+c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight)
+{
+ gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
+ switch (pdf14pct->params.pdf14_op) {
+ case PDF14_PUSH_DEVICE: return 0; /* Applies to all bands. */
+ case PDF14_POP_DEVICE: return 0; /* Applies to all bands. */
+ case PDF14_BEGIN_TRANS_GROUP:
+ { gs_int_rect rect;
+ int code;
+
+ code = pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm, &pdf14pct->params.bbox, &rect);
+ *ry = rect.p.y;
+ *rheight = rect.q.y - rect.p.y;
+ return 1; /* Push croping. */
+ }
+ case PDF14_END_TRANS_GROUP: return 2; /* Pop cropping. */
+ case PDF14_BEGIN_TRANS_MASK: return 3; /* Same cropping as before. */
+ case PDF14_END_TRANS_MASK: return 3;
+ case PDF14_SET_BLEND_PARAMS: return 3;
+ }
+ return 0;
+}
+
+/*
* This routine will check to see if the color component name matches those
* that are available amoung the current device's color components. If the
* color name is known to the output device then we add it to the list of
Modified: trunk/gs/src/gdevp14.h
===================================================================
--- trunk/gs/src/gdevp14.h 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gdevp14.h 2008-03-03 16:01:12 UTC (rev 8585)
@@ -56,6 +56,7 @@
gs_int_rect bbox;
pdf14_buf *maskbuf; /* Save pdf14_ctx_s::maksbuf. */
bool idle;
+ uint mask_id;
};
struct pdf14_ctx_s {
Modified: trunk/gs/src/gsalphac.c
===================================================================
--- trunk/gs/src/gsalphac.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gsalphac.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -104,7 +104,8 @@
gx_default_composite_is_closing,
gx_default_composite_is_friendly,
gx_default_composite_clist_write_update,
- gx_default_composite_clist_read_update
+ gx_default_composite_clist_read_update,
+ gx_default_composite_get_cropping
}
};
typedef struct gs_composite_alpha_s {
@@ -150,7 +151,7 @@
}
static int
-c_alpha_write(const gs_composite_t * pcte, byte * data, uint * psize)
+c_alpha_write(const gs_composite_t * pcte, byte * data, uint * psize, gx_device_clist_writer *cdev)
{
uint size = *psize;
uint used;
Modified: trunk/gs/src/gsovrc.c
===================================================================
--- trunk/gs/src/gsovrc.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gsovrc.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -129,7 +129,7 @@
* list device.
*/
static int
-c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize)
+c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
{
const gs_overprint_params_t * pparams = &((const gs_overprint_t *)pct)->params;
byte flags = 0;
@@ -230,7 +230,8 @@
c_overprint_is_closing,
gx_default_composite_is_friendly,
gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
- gx_default_composite_clist_read_update /* procs.composite_clist_reade_update */
+ gx_default_composite_clist_read_update, /* procs.composite_clist_reade_update */
+ gx_default_composite_get_cropping /* procs.composite_get_cropping */
} /* procs */
};
Modified: trunk/gs/src/gstparam.h
===================================================================
--- trunk/gs/src/gstparam.h 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gstparam.h 2008-03-03 16:01:12 UTC (rev 8585)
@@ -84,6 +84,7 @@
bool Knockout;
bool image_with_SMask;
bool idle;
+ uint mask_id;
} gs_transparency_group_params_t;
/* Define the parameter structure for a transparency mask. */
@@ -118,6 +119,7 @@
bool function_is_identity;
bool idle;
bool replacing;
+ uint mask_id;
byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE];
} gx_transparency_mask_params_t;
Modified: trunk/gs/src/gstrans.c
===================================================================
--- trunk/gs/src/gstrans.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gstrans.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -150,7 +150,7 @@
{
gs_imager_state * pis = (gs_imager_state *)pgs;
gx_device * dev = pgs->device;
- gx_device * pdf14dev;
+ gx_device *pdf14dev = NULL;
int code;
/*
@@ -174,6 +174,7 @@
ptgp->Isolated = false;
ptgp->Knockout = false;
ptgp->image_with_SMask = false;
+ ptgp->mask_id = 0;
}
int
@@ -234,6 +235,7 @@
tgp.Isolated = pparams->Isolated;
tgp.Knockout = pparams->Knockout;
tgp.idle = pparams->idle;
+ tgp.mask_id = pparams->mask_id;
pis->opacity.alpha = pparams->opacity.alpha;
pis->shape.alpha = pparams->shape.alpha;
pis->blend_mode = pparams->blend_mode;
@@ -354,6 +356,7 @@
tmp.function_is_identity = pparams->function_is_identity;
tmp.idle = pparams->idle;
tmp.replacing = pparams->replacing;
+ tmp.mask_id = pparams->mask_id;
memcpy(tmp.transfer_fn, pparams->transfer_fn, size_of(tmp.transfer_fn));
if_debug8('v', "[v](0x%lx)gx_begin_transparency_mask [%g %g %g %g]\n\
subtype = %d Background_components = %d %s\n",
Modified: trunk/gs/src/gstrans.h
===================================================================
--- trunk/gs/src/gstrans.h 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gstrans.h 2008-03-03 16:01:12 UTC (rev 8585)
@@ -88,8 +88,9 @@
gs_transparency_source_t shape;
bool mask_is_image;
gs_matrix ctm;
- bool idle;
bool replacing;
+ bool idle; /* For clist reader.*/
+ uint mask_id; /* For clist reader.*/
};
#ifndef gs_pdf14trans_params_DEFINED
Modified: trunk/gs/src/gxclimag.c
===================================================================
--- trunk/gs/src/gxclimag.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gxclimag.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -856,8 +856,14 @@
gs_imager_state * pis, gs_memory_t * mem)
{
byte * dp;
- uint size = 0;
- int code = pcte->type->procs.write(pcte, 0, &size);
+ uint size = 0, size_dummy;
+ gx_device_clist_writer * const cdev =
+ &((gx_device_clist *)dev)->writer;
+ int ry, rheight, cropping_op;
+ int band_height = cdev->page_info.band_params.BandHeight;
+ int last_band = (cdev->height + band_height - 1) / band_height;
+ int first_band = 0, no_of_bands = last_band + 1;
+ int code = pcte->type->procs.write(pcte, 0, &size, cdev);
/* determine the amount of space required */
if (code < 0 && code != gs_error_rangecheck)
@@ -870,41 +876,78 @@
if (code < 0)
return code;
-#if 0 /* Disabled sinse c_pdf14trans_write includes CTM into the pdf14 compositor parameters. */
- if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
- gx_device_clist_writer * const cdev =
- &((gx_device_clist *)dev)->writer;
- int len = cmd_write_ctm_return_length(cdev, &ctm_only(pis));
+ code = pcte->type->procs.get_cropping(pcte, &ry, &rheight);
+ if (code < 0)
+ return code;
+ cropping_op = code;
+ if (cropping_op == 1) {
+ first_band = ry / band_height;
+ last_band = (ry + rheight + band_height - 1) / band_height;
+ } else if (cropping_op > 1) {
+ first_band = cdev->cropping_min / band_height;
+ last_band = (cdev->cropping_max + band_height - 1) / band_height;
+ }
+ if (last_band - first_band > no_of_bands * 2 / 3) {
+ /* Covering many bands, so write "all bands" command for shorter clist. */
+ cropping_op = 0;
+ }
+ if (cropping_op == 0) {
+ /* overprint applies to all bands */
+ size_dummy = size;
+ code = set_cmd_put_all_op( dp,
+ (gx_device_clist_writer *)dev,
+ cmd_opv_extend,
+ size );
+ if (code < 0)
+ return code;
- code = set_cmd_put_all_op(dp, (gx_device_clist_writer *)dev,
- cmd_opv_set_ctm, len + 1);
+ /* insert the command and compositor identifier */
+ dp[1] = cmd_opv_ext_create_compositor;
+ dp[2] = pcte->type->comp_id;
+
+ /* serialize the remainder of the compositor */
+ if ((code = pcte->type->procs.write(pcte, dp + 3, &size_dummy, cdev)) < 0)
+ ((gx_device_clist_writer *)dev)->cnext = dp;
+ return code;
+ }
+ if (cropping_op == 1) {
+ code = clist_writer_push_cropping(cdev, ry, rheight);
if (code < 0)
return code;
- /* fixme: would like to set pcls->known for covered bands. */
- code = cmd_write_ctm(&ctm_only(pis), dp, len);
+ }
+ {
+ /* The pdf14 compositor could be applied
+ only to bands covered by the pcte->params.bbox. */
+ cmd_rects_enum_t re;
+
+ RECT_ENUM_INIT(re, cdev->cropping_min, cdev->cropping_max - cdev->cropping_min);
+ do {
+ RECT_STEP_INIT(re);
+ re.pcls->band_complexity.nontrivial_rops = true;
+ do {
+ code = set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_extend, size);
+ if (code >= 0) {
+ size_dummy = size;
+ dp[1] = cmd_opv_ext_create_compositor;
+ dp[2] = pcte->type->comp_id;
+ code = pcte->type->procs.write(pcte, dp + 3, &size_dummy, cdev);
+ }
+ } while (RECT_RECOVER(code));
+ if (code < 0 && SET_BAND_CODE(code))
+ goto error_in_rect;
+ re.y += re.height;
+ continue;
+ error_in_rect:
+ if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 &&
+ SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0))
+ return re.band_code;
+ } while (re.y < re.yend);
+ }
+ if (cropping_op == 2) {
+ code = clist_writer_pop_cropping(cdev);
if (code < 0)
return code;
- state_update(ctm);
}
-#endif
-
- /* overprint applies to all bands */
- /* fixme: optimize: the pdf14 compositor could be applied
- only to bands covered by the pcte->params.bbox. */
- code = set_cmd_put_all_op( dp,
- (gx_device_clist_writer *)dev,
- cmd_opv_extend,
- size );
- if (code < 0)
- return code;
-
- /* insert the command and compositor identifier */
- dp[1] = cmd_opv_ext_create_compositor;
- dp[2] = pcte->type->comp_id;
-
- /* serialize the remainder of the compositor */
- if ((code = pcte->type->procs.write(pcte, dp + 3, &size)) < 0)
- ((gx_device_clist_writer *)dev)->cnext = dp;
return code;
}
Modified: trunk/gs/src/gxclist.c
===================================================================
--- trunk/gs/src/gxclist.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gxclist.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -470,6 +470,8 @@
cdev->cropping_min = cdev->save_cropping_min = 0;
cdev->cropping_max = cdev->save_cropping_max = cdev->height;
cdev->cropping_stack = NULL;
+ cdev->cropping_level = 0;
+ cdev->mask_id_count = cdev->mask_id = cdev->temp_mask_id = 0;
return 0;
}
/*
@@ -883,9 +885,6 @@
return min(dev->height - start, band_height);
}
-
-
-
/* copy constructor if from != NULL
* default constructor if from == NULL
*/
@@ -916,10 +915,14 @@
if (buf == NULL)
return_error(gs_error_VMerror);
+ if_debug1('v', "[v]push cropping[%d]\n", cdev->cropping_level);
buf->next = cdev->cropping_stack;
cdev->cropping_stack = buf;
buf->cropping_min = cdev->cropping_min;
buf->cropping_max = cdev->cropping_max;
+ buf->mask_id = cdev->mask_id;
+ buf->temp_mask_id = cdev->temp_mask_id;
+ cdev->cropping_level++;
return 0;
}
@@ -944,7 +947,11 @@
return_error(gs_error_unregistered); /*Must not happen. */
cdev->cropping_min = buf->cropping_min;
cdev->cropping_max = buf->cropping_max;
+ cdev->mask_id = buf->mask_id;
+ cdev->temp_mask_id = buf->temp_mask_id;
cdev->cropping_stack = buf->next;
+ cdev->cropping_level--;
+ if_debug1('v', "[v]pop cropping[%d]\n", cdev->cropping_level);
gs_free_object(cdev->memory, buf, "clist_writer_transparency_pop");
return 0;
}
@@ -953,6 +960,7 @@
clist_writer_check_empty_cropping_stack(gx_device_clist_writer *cdev)
{
if (cdev->cropping_stack != NULL) {
+ if_debug1('v', "[v]Error: left %d cropping(s)\n", cdev->cropping_level);
return_error(gs_error_unregistered); /* Must not happen */
}
return 0;
Modified: trunk/gs/src/gxclist.h
===================================================================
--- trunk/gs/src/gxclist.h 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gxclist.h 2008-03-03 16:01:12 UTC (rev 8585)
@@ -219,7 +219,7 @@
gs_id id; /* space->id for comparisons */
const gs_color_space *space;
} clist_color_space_t;
-typedef struct gx_device_clist_writer_s {
+struct gx_device_clist_writer_s {
gx_device_clist_common_members; /* (must be first) */
int error_code; /* error returned by cmd_put_op */
gx_clist_state *states; /* current state of each band */
@@ -266,9 +266,17 @@
gs_pattern1_instance_t *pinst; /* Used when it is a pattern clist. */
int cropping_min, cropping_max;
int save_cropping_min, save_cropping_max;
+ int cropping_level;
+ clist_writer_cropping_buffer_t *cropping_stack;
ulong ins_count;
- clist_writer_cropping_buffer_t *cropping_stack;
-} gx_device_clist_writer;
+ uint mask_id_count;
+ uint mask_id;
+ uint temp_mask_id; /* Mask id of a mask of an image with SMask. */
+};
+#ifndef gx_device_clist_writer_DEFINED
+#define gx_device_clist_writer_DEFINED
+typedef struct gx_device_clist_writer_s gx_device_clist_writer;
+#endif
/* Bits for gx_device_clist_writer.disable_mask. Bit set disables behavior */
#define clist_disable_fill_path (1 << 0)
Modified: trunk/gs/src/gxclpath.c
===================================================================
--- trunk/gs/src/gxclpath.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gxclpath.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -604,6 +604,8 @@
code = gx_default_fill_path(dev, pis, ppath, params, pdcolor, pcpath);
cdev->cropping_min = cdev->save_cropping_min;
cdev->cropping_max = cdev->save_cropping_max;
+ if_debug2('v', "[v] clist_fill_path: restore cropping_min=%d croping_max=%d\n",
+ cdev->save_cropping_min, cdev->save_cropping_max);
return code;
}
if ( (cdev->disable_mask & clist_disable_fill_path) ||
@@ -647,6 +649,8 @@
cdev->save_cropping_max = cdev->cropping_max;
cdev->cropping_min = max(ry, cdev->cropping_min);
cdev->cropping_max = min(ry + rheight, cdev->cropping_max);
+ if_debug2('v', "[v] clist_fill_path: narrow cropping_min=%d croping_max=%d\n",
+ cdev->save_cropping_min, cdev->save_cropping_max);
RECT_ENUM_INIT(re, ry, rheight);
do {
RECT_STEP_INIT(re);
Modified: trunk/gs/src/gxclrast.c
===================================================================
--- trunk/gs/src/gxclrast.c 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gxclrast.c 2008-03-03 16:01:12 UTC (rev 8585)
@@ -388,17 +388,24 @@
}
}
-static inline void
+static inline int
drop_compositor_queue(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last,
- gs_composite_t *pcomp_from, gs_memory_t *mem)
+ gs_composite_t *pcomp_from, gs_memory_t *mem, int x0, int y0,
+ gs_imager_state *pis)
{
gs_composite_t *pcomp;
do {
+ int code;
+
pcomp = *ppcomp_last;
dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
+ code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pis);
+ if (code < 0)
+ return code;
free_compositor(pcomp, mem);
} while (pcomp != pcomp_from);
+ return 0;
}
static int
@@ -1416,6 +1423,7 @@
goto out;
break;
case cmd_opv_ext_create_compositor:
+ if_debug0('L', " ext_create_compositor\n");
cbuf.ptr = cbp;
/*
* The screen phase may have been changed during
@@ -1484,7 +1492,9 @@
} else if (code == 5) {
/* Annihilate the last compositors. */
enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
- drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem);
+ code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &imager_state);
+ if (code < 0)
+ goto out;
} else if (code == 6) {
/* Mark as idle. */
enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
@@ -1577,6 +1587,7 @@
{
uint ht_size;
+ if_debug0('L', " ext_put_halftone\n");
enc_u_getw(ht_size, cbp);
code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
if (code < 0)
@@ -1584,6 +1595,7 @@
}
break;
case cmd_opv_ext_put_ht_seg:
+ if_debug0('L', " ext_put_ht_seg\n");
cbuf.ptr = cbp;
code = read_ht_segment(&ht_buff, &cbuf,
&imager_state, tdev,
@@ -2001,8 +2013,12 @@
ht_buff.ht_size = 0;
ht_buff.read_size = 0;
- if (pcomp_last != NULL)
- drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem);
+ if (pcomp_last != NULL) {
+ int code1 = drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem, x0, y0, &imager_state);
+
+ if (code == 0)
+ code = code1;
+ }
rc_decrement(pcs, "clist_playback_band");
gx_cpath_free(&clip_path, "clist_render_band exit");
gx_path_free(&path, "clist_render_band exit");
Modified: trunk/gs/src/gxcomp.h
===================================================================
--- trunk/gs/src/gxcomp.h 2008-03-03 11:57:42 UTC (rev 8584)
+++ trunk/gs/src/gxcomp.h 2008-03-03 16:01:12 UTC (rev 8585)
@@ -55,13 +55,16 @@
#ifndef gs_imager_state_DEFINED
# define gs_imager_state_DEFINED
typedef struct gs_imager_state_s gs_imager_state;
-
#endif
#ifndef gx_device_DEFINED
# define gx_device_DEFINED
typedef struct gx_device_s gx_device;
+#endif
+#ifndef gx_device_clist_writer_DEFINED
+#define gx_device_clist_writer_DEFINED
+typedef struct gx_device_clist_writer_s gx_device_clist_writer;
#endif
typedef struct gs_composite_type_procs_s {
@@ -91,7 +94,7 @@
* not changed.
*/
#define composite_write_proc(proc)\
- int proc(const gs_composite_t *pcte, byte *data, uint *psize)
+ int proc(const gs_composite_t *pcte, byte *data, uint *psize, gx_device_clist_writer *cdev)
composite_write_proc((*write));
/*
@@ -146,6 +149,13 @@
gs_imager_state * pis, gs_memory_t * mem)
composite_clist_read_update((*clist_compositor_read_update));
+ /*
+ * Get compositor cropping.
+ */
+#define composite_get_cropping_proc(proc)\
+ int proc(const gs_composite_t * pcte, int *ry, int *rheight)
+ composite_get_cropping_proc((*get_cropping));
+
} gs_composite_type_procs_t;
typedef struct gs_composite_type_s {
@@ -175,6 +185,11 @@
composite_clist_read_update(gx_default_composite_clist_read_update);
/*
+ * Default implementation for get_cropping doesn't return a cropping.
+ */
+composite_get_cropping_proc(gx_default_composite_get_cropping);
+
+/*
* Compositing objects are reference-counted, because graphics states will
* eventually reference them. Note that the common part has no
* garbage-collectible pointers and is never actually instantiated, so no
More information about the gs-cvs
mailing list