[gs-cvs] rev 8584 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Mon Mar 3 03:57:43 PST 2008
Author: leonardo
Date: 2008-03-03 03:57:42 -0800 (Mon, 03 Mar 2008)
New Revision: 8584
Modified:
trunk/gs/src/gdevp14.c
trunk/gs/src/gxcldev.h
trunk/gs/src/gxclist.c
trunk/gs/src/gxclist.h
trunk/gs/src/gxclpath.c
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/gdevp14.c
===================================================================
--- trunk/gs/src/gdevp14.c 2008-03-03 11:42:33 UTC (rev 8583)
+++ trunk/gs/src/gdevp14.c 2008-03-03 11:57:42 UTC (rev 8584)
@@ -2164,9 +2164,8 @@
int code, sbyte, bit, count;
int run_length, startx, current_bit, bit_value;
gx_color_index current_color;
- pdf14_device *pdev = (pdf14_device *)dev;
- fit_copy(pdev, base, sourcex, sraster, id, x, y, w, h);
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
line = base + (sourcex >> 3);
sbit = sourcex & 7;
first_bit = 7 - sbit;
@@ -2242,6 +2241,22 @@
return pdf14_mark_fill_rectangle(dev, x, y, w, h, color);
}
+static int
+pdf14_compute_group_device_int_rect(const gs_matrix *ctm, const gs_rect *pbbox, gs_int_rect *rect)
+{
+ gs_rect dev_bbox;
+ int code;
+
+ code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
+ if (code < 0)
+ return code;
+ rect->p.x = (int)floor(dev_bbox.p.x);
+ rect->p.y = (int)floor(dev_bbox.p.y);
+ rect->q.x = (int)ceil(dev_bbox.q.x);
+ rect->q.y = (int)ceil(dev_bbox.q.y);
+ return 0;
+}
+
static int
pdf14_begin_transparency_group(gx_device *dev,
const gs_transparency_group_params_t *ptgp,
@@ -2252,17 +2267,12 @@
{
pdf14_device *pdev = (pdf14_device *)dev;
double alpha = pis->opacity.alpha * pis->shape.alpha;
- gs_rect dev_bbox;
gs_int_rect rect;
int code;
- code = gs_bbox_transform(pbbox, &ctm_only(pis), &dev_bbox);
+ code = pdf14_compute_group_device_int_rect(&ctm_only(pis), pbbox, &rect);
if (code < 0)
return code;
- rect.p.x = (int)floor(dev_bbox.p.x);
- rect.p.y = (int)floor(dev_bbox.p.y);
- rect.q.x = (int)ceil(dev_bbox.q.x);
- rect.q.y = (int)ceil(dev_bbox.q.y);
rect_intersect(rect, pdev->ctx->rect);
/* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
if (rect.q.x < rect.p.x)
@@ -3244,8 +3254,8 @@
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
static composite_is_closing_proc(c_pdf14trans_is_closing);
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_clist_write_update(c_pdf14trans_clist_write_update);
+static composite_clist_read_update(c_pdf14trans_clist_read_update);
/*
@@ -4403,16 +4413,13 @@
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
gx_device ** pcdev, gs_imager_state * pis, gs_memory_t * mem)
{
+ gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
pdf14_clist_device * p14dev;
int code = 0;
- { gx_device_clist_writer * const cdev =
- &((gx_device_clist *)dev)->writer;
+ state_update(ctm); /* See c_pdf14trans_write. */
- state_update(ctm); /* See c_pdf14trans_write. */
- }
-
/* We only handle the push/pop operations */
switch (pdf14pct->params.pdf14_op) {
case PDF14_PUSH_DEVICE:
@@ -4453,7 +4460,22 @@
# else
code = 0;
# endif
+ code = clist_writer_check_empty_cropping_stack(cdev);
break;
+ case PDF14_BEGIN_TRANS_GROUP:
+ { pdf14_device *pdev = (pdf14_device *)*pcdev;
+ gs_int_rect rect;
+
+ code = pdf14_compute_group_device_int_rect(&ctm_only(pis),
+ &pdf14pct->params.bbox, &rect);
+
+ if (code >= 0)
+ code = clist_writer_push_cropping(cdev, rect.p.y, rect.q.y - rect.p.y);
+ }
+ break;
+ case PDF14_END_TRANS_GROUP:
+ code = clist_writer_pop_cropping(cdev);
+ break;
default:
break; /* do nothing for remaining ops */
}
Modified: trunk/gs/src/gxcldev.h
===================================================================
--- trunk/gs/src/gxcldev.h 2008-03-03 11:42:33 UTC (rev 8583)
+++ trunk/gs/src/gxcldev.h 2008-03-03 11:57:42 UTC (rev 8584)
@@ -722,4 +722,9 @@
int top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end);
#endif
+int clist_writer_push_no_cropping(gx_device_clist_writer *cdev);
+int clist_writer_push_cropping(gx_device_clist_writer *cdev, int ry, int rheight);
+int clist_writer_pop_cropping(gx_device_clist_writer *cdev);
+int clist_writer_check_empty_cropping_stack(gx_device_clist_writer *cdev);
+
#endif /* gxcldev_INCLUDED */
Modified: trunk/gs/src/gxclist.c
===================================================================
--- trunk/gs/src/gxclist.c 2008-03-03 11:42:33 UTC (rev 8583)
+++ trunk/gs/src/gxclist.c 2008-03-03 11:57:42 UTC (rev 8584)
@@ -45,6 +45,7 @@
case 1: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
cdev->writer.color_space.space : 0));
case 2: return ENUM_OBJ(cdev->writer.pinst);
+ case 3: return ENUM_OBJ(cdev->writer.cropping_stack);
default:
return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
sizeof(gs_imager_state), index - 3);
@@ -75,6 +76,7 @@
RELOC_VAR(cdev->writer.color_space.space);
}
RELOC_VAR(cdev->writer.pinst);
+ RELOC_VAR(cdev->writer.cropping_stack);
RELOC_USING(st_imager_state, &cdev->writer.imager_state,
sizeof(gs_imager_state));
} else {
@@ -87,6 +89,7 @@
}
} RELOC_PTRS_END
public_st_device_clist();
+private_st_clist_writer_cropping_buffer();
/* Forward declarations of driver procedures */
dev_proc_open_device(clist_open);
@@ -466,6 +469,7 @@
cdev->image_enum_id = gs_no_id;
cdev->cropping_min = cdev->save_cropping_min = 0;
cdev->cropping_max = cdev->save_cropping_max = cdev->height;
+ cdev->cropping_stack = NULL;
return 0;
}
/*
@@ -902,3 +906,54 @@
#endif
}
}
+
+int
+clist_writer_push_no_cropping(gx_device_clist_writer *cdev)
+{
+ clist_writer_cropping_buffer_t *buf = gs_alloc_struct(cdev->memory,
+ clist_writer_cropping_buffer_t,
+ &st_clist_writer_cropping_buffer, "clist_writer_transparency_push");
+
+ if (buf == NULL)
+ return_error(gs_error_VMerror);
+ buf->next = cdev->cropping_stack;
+ cdev->cropping_stack = buf;
+ buf->cropping_min = cdev->cropping_min;
+ buf->cropping_max = cdev->cropping_max;
+ return 0;
+}
+
+int
+clist_writer_push_cropping(gx_device_clist_writer *cdev, int ry, int rheight)
+{
+ int code = clist_writer_push_no_cropping(cdev);
+
+ if (code < 0)
+ return 0;
+ cdev->cropping_min = max(cdev->cropping_min, ry);
+ cdev->cropping_max = min(cdev->cropping_max, ry + rheight);
+ return 0;
+}
+
+int
+clist_writer_pop_cropping(gx_device_clist_writer *cdev)
+{
+ clist_writer_cropping_buffer_t *buf = cdev->cropping_stack;
+
+ if (buf == NULL)
+ return_error(gs_error_unregistered); /*Must not happen. */
+ cdev->cropping_min = buf->cropping_min;
+ cdev->cropping_max = buf->cropping_max;
+ cdev->cropping_stack = buf->next;
+ gs_free_object(cdev->memory, buf, "clist_writer_transparency_pop");
+ return 0;
+}
+
+int
+clist_writer_check_empty_cropping_stack(gx_device_clist_writer *cdev)
+{
+ if (cdev->cropping_stack != NULL) {
+ 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:42:33 UTC (rev 8583)
+++ trunk/gs/src/gxclist.h 2008-03-03 11:57:42 UTC (rev 8584)
@@ -198,6 +198,21 @@
/* (Strokes with longer patterns are converted to fills.) */
#define cmd_max_dash 11
+/* Define a clist cropping buffer,
+ which represents a cropping stack element while clist writing. */
+typedef struct clist_writer_cropping_buffer_s clist_writer_cropping_buffer_t;
+
+struct clist_writer_cropping_buffer_s {
+ int cropping_min, cropping_max;
+ uint mask_id, temp_mask_id;
+ clist_writer_cropping_buffer_t *next;
+};
+
+#define private_st_clist_writer_cropping_buffer()\
+ gs_private_st_ptrs1(st_clist_writer_cropping_buffer,\
+ clist_writer_cropping_buffer_t, "clist_writer_transparency_buffer",\
+ clist_writer_cropping_buffer_enum_ptrs, clist_writer_cropping_buffer_reloc_ptrs, next)
+
/* Define the state of a band list when writing. */
typedef struct clist_color_space_s {
byte byte1; /* see cmd_opv_set_color_space in gxclpath.h */
@@ -252,6 +267,7 @@
int cropping_min, cropping_max;
int save_cropping_min, save_cropping_max;
ulong ins_count;
+ clist_writer_cropping_buffer_t *cropping_stack;
} gx_device_clist_writer;
/* Bits for gx_device_clist_writer.disable_mask. Bit set disables behavior */
@@ -292,7 +308,7 @@
"gx_device_clist", 0, device_clist_enum_ptrs, device_clist_reloc_ptrs,\
gx_device_finalize)
#define st_device_clist_max_ptrs\
- (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 3)
+ (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 4)
#define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0)
Modified: trunk/gs/src/gxclpath.c
===================================================================
--- trunk/gs/src/gxclpath.c 2008-03-03 11:42:33 UTC (rev 8583)
+++ trunk/gs/src/gxclpath.c 2008-03-03 11:57:42 UTC (rev 8584)
@@ -643,6 +643,8 @@
The graphics library will call us again with subdividing
the shading into trapezoids and rectangles.
Narrow cropping_min, croping_max for such calls. */
+ cdev->save_cropping_min = cdev->cropping_min;
+ cdev->save_cropping_max = cdev->cropping_max;
cdev->cropping_min = max(ry, cdev->cropping_min);
cdev->cropping_max = min(ry + rheight, cdev->cropping_max);
RECT_ENUM_INIT(re, ry, rheight);
More information about the gs-cvs
mailing list