[gs-cvs] rev 7149 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Wed Nov 1 13:18:41 PST 2006


Author: leonardo
Date: 2006-11-01 13:18:41 -0800 (Wed, 01 Nov 2006)
New Revision: 7149

Modified:
   trunk/gs/src/gxcpath.c
   trunk/gs/src/gxfill.c
Log:
Fix : When filling a path with a shading, the filling rule was missed. 

DETAILS :

1. Unwing the rev 7114 patch due to a significant slowdown
   for filling a path with a shading (gxfill.c).

2. A minor change to gxfill.c : removed a redundant assignment to fo.lop .

3. The old code always used the non-zero winding rule,
   because gx_cpath_to_path misses the winding rule
   when called from gx_default_fill_path.
   See commet in code.
   This is the real fix for the problem.

4. pcpath->rule sometimes was not initialized when pcpath->path_valid is true (gxcpath.c)

We don't like that gx_default_fill_path creates a big clipping path,
which then converts into a path, which then is being intersected 
with a rectangle and/or parallelogram(the shading BBox) in gs_shading_fill_path.
The biggest time expence in this chain is the sorting a lot of 
rectangles when gx_cpath_intersect_path_slow applies the filling
algorithm to compute the intersection. In many cases the 
the rectangle is simply the bounding box of the path,
but it still needs the clipping path planarization, because 
the "planarized" property isn't stored in the path structure.

We tried to optimize against it, but didn't succeed with no raster differences.
Delaying that optimization for better times.
Due to a short time frame we need to make this patch smaller and simpler.
 
EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gxcpath.c
===================================================================
--- trunk/gs/src/gxcpath.c	2006-11-01 19:58:48 UTC (rev 7148)
+++ trunk/gs/src/gxcpath.c	2006-11-01 21:18:41 UTC (rev 7149)
@@ -655,6 +655,7 @@
 	if (path_valid) {
 	    gx_path_assign_preserve(&pcpath->path, ppath_orig);
 	    pcpath->path_valid = true;
+	    pcpath->rule = rule;
 	} else {
 	    code = gx_cpath_path_list_new(pcpath->path.memory, NULL, rule, 
 					    ppath_orig, next, &pcpath->path_list);

Modified: trunk/gs/src/gxfill.c
===================================================================
--- trunk/gs/src/gxfill.c	2006-11-01 19:58:48 UTC (rev 7148)
+++ trunk/gs/src/gxfill.c	2006-11-01 21:18:41 UTC (rev 7149)
@@ -417,7 +417,6 @@
     fo.ymin = ibox.p.y;
     fo.ymax = ibox.q.y;
     fo.dev = dev;
-    fo.lop = lop;
     fo.pbox = &sbox;
     fo.rule = params->rule;
     fo.is_spotan = is_spotan_device(dev);
@@ -553,8 +552,7 @@
 {
     int code;
 
-    if ((gx_dc_is_pattern2_color(pdevc) || pdevc->type == &gx_dc_type_data_ht_colored) &&
-	params->rule == -1) {
+    if ((gx_dc_is_pattern2_color(pdevc) || pdevc->type == &gx_dc_type_data_ht_colored)) {
 	/*  Optimization for shading and halftone fill :
 	    The general filling algorithm subdivides the fill region into 
 	    trapezoid or rectangle subregions and then paints each subregion 
@@ -598,8 +596,23 @@
 			    cb.p.x, cb.p.y, cb.q.x - cb.p.x, cb.q.y - cb.p.y,
 			    dev, pis->log_op, rs);
 	    } else {
-		/* Shading fill algorithm fills an area restricted with a path,
-		   so we need to convert cpath into path .*/
+		/* The shading fill algorithm fills an area restricted with a path,
+		   so we need to convert cpath into path.
+
+		   We can't set a clipping device here like we did for 
+		   gx_dc_type_data_ht_colored, because the shading itself
+		   may add another clipping with its BBox,
+		   which may be transformed into a parallelogram.
+		   We don't want two clipping devices chained consequently.
+		 */
+		if (params->rule != gx_rule_winding_number) {
+		    /* HACK : Rather cpath_intersection contains a valid path,
+		       it is not planarized to a simple winding path,
+		       so we can't use the contained path.
+		       Reset path_valid against using it.
+		    */
+		    cpath_intersection.path_valid = false;
+		}
 		code = gx_cpath_to_path(&cpath_intersection, &path_intersection);
 		if (code >= 0)
 		    code = gx_dc_pattern2_fill_path(pdevc, &path_intersection, NULL,  pdev);



More information about the gs-cvs mailing list