[gs-cvs] rev 8585 - trunk/gs/src - wrong log message.
Leonardo
leonardo at artifex.com
Mon Mar 3 07:17:59 PST 2008
The revision 8585 has been committed with a wrong log message.
I fixed the repository with the correct one :
Fix (clist) : Crop transparency commands while clist writing, step 3.
DETAILS :
This really crops transparency compositor commands with bands
that are covered by the transparency bbox.
Actually the statement above has one exception. When a transparency bbox
covers more that 2/3 of all bands, we still write the commands to
the "all bands" list for a shorter clist file. We noticed that
the clist playback time strongly depends on the file size.
1. The new method gs_composite_type_procs_t::get_cropping
replies what bands are covered by the compositor.
When it gives a non-trivial result, clist_create_compositor
writes the compositor command to those bands,
which are covered with the cropping (Exception :
if too many bands are covered, it writes the command to
the "for all bands" list).
2. Since some bands skip some compositor commands,
while clist reading the association of masks to groups
becomes more complex. Before this patch each group
was associates with the mask, which was created immediately
before it at same transparency stack level.
After this patch some groups may be skipped, so that
clist reader may recieve extra masks, because masks are
still use the container's group bbox. For skipping such extra masks
we provide a numeric identifier of a mask, which is named mask_id.
Here is how it works :
2.1. All masks recieve serial numbers (mask_id) while clist writing.
2.2. Each mask command is written with its mask_id.
2.3. Each group command is writen with mask_id,
which belongs to the mask that is assocuated with the group.
2.4. While clist playback pdf14_pop_transparency_group checks whether
the mask amd the group have same mask_id. If not, the mask is extra
and it must be droped.
2.5. Note the old assiciation logic is still working,
and it may skip some masks as well.
2.6. If the rasterization happens with no clist, mask_id is always zero.
In this case the old logics is only working.
Maybe we'll provide non-zero values someday.
2.7. See comments in code for more details.
3. The method gs_composite_type_procs_t::clist_compositor_write_update
is now some generalized. Before this patch it only updates the clist writer
state
with the compositor features. With this patch it also adds
some information from the clist writer state to the compositor parameters.
Particularly it provides mask_id to the compositor command.
Thus now it updates *both* clist writer and the compositor parameters
to comply each another. For a while, in order to simplify the patch,
the compositor argument is still 'const'. Will need to fix someday.
4. Now we need to save mask_id in a stack that reflects the
transparency nesting. The cropping stack, which was introduced
in the last patch, now works for that. To provide that
we add mask_id to clist_writer_cropping_buffer_s,
and use clist_writer_push_no_cropping to save amsk_id
over inner groups.
5. state_update(ctm) in c_pdf14trans_clist_write_update is replaced
with code, which updates CTM from the transparency compositor command.
The old code is not fully correct, because it takes CTM from the imager
state,
rather we havn't got prcatical cases when it gives a wrong result.
6. drop_compositor_queue now calls adjust_ctm for compositors being dropped.
The old code is incorrect because it can miss a CTM update when
a compositor sets some CTM and later a non-compositor object
sets same CTM. In this case the clist writer skips the second CTM on
writing,
and skipping the first in the clist reader will miss the CTM completely.
We haven't got practical cases for that.
7. Improved some debug printing.
EXPECTED DIFFERENCES :
None.
Leo.
----- Original Message -----
From: <leonardo at ghostscript.com>
To: <gs-cvs at ghostscript.com>
Sent: Monday, March 03, 2008 7:01 PM
Subject: [gs-cvs] rev 8585 - trunk/gs/src
> 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
>
> _______________________________________________
> gs-cvs mailing list
> gs-cvs at ghostscript.com
> http://www.ghostscript.com/mailman/listinfo/gs-cvs
>
More information about the gs-cvs
mailing list