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);

_______________________________________________
gs-cvs mailing list
gs-cvs@ghostscript.com
http://www.ghostscript.com/mailman/listinfo/gs-cvs
