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

leonardo at ghostscript.com leonardo at ghostscript.com
Wed May 9 08:45:54 PDT 2007


Author: leonardo
Date: 2007-05-09 08:45:54 -0700 (Wed, 09 May 2007)
New Revision: 7936

Modified:
   trunk/gs/src/gxshade4.h
   trunk/gs/src/gxshade6.c
Log:
Fix (shadings) : The decomposition limit must depend on resolution.

DETAILS : 

This partially improves performance for the test case of 
the bug 689189 "PDF fails with /unregistered in --shfill--".

The old code limits the decomposition od a shading with 1 pisxel.
It gives a good precision for low resolution devices,
such as display with 72dpi. However for high resolution devices the,
decomposition limit may be bigger, because tinny parts are not visible.
Now we make it be dependent on the device resolution.
It speeds up the high resolution rendering with qwickly varying colors.
The worfker formula is :

	decomposition_limit = float2fixed(pfs->dev->HWResolution / 72)

EXPECTED DIFFERENCES :

Minor difference in colors with most shadings :



"442-01.ps" 
"446-01-fixed.ps" 
"464-01-fixed.ps" 
"478-01.ps" 
"483-01.ps" 
"483-05-fixed.ps" 
"BEST8-99-Path.fh7.pdf" 
"Bug688631.pdf" 
"chilis_black.pdf" 
"Clarke Tate Manns Chinese.ai" 
"gradmesh.ai" 
"Openhuis_pdf_zw.pdf" 
"self-intersect2.ps" 
"SmoothShading.pdf" 
"self-intersect2.ps" 
"SmoothShading.pdf" 
"STEUER-RollingMesh 1(linear).ai" 
"STEUER-RollingMesh 2(radial).ai" 
"STEUER-RollingMesh 3(Final).ai" 
"Testform.v1.0.2.pdf" 


Modified: trunk/gs/src/gxshade4.h
===================================================================
--- trunk/gs/src/gxshade4.h	2007-05-09 11:34:33 UTC (rev 7935)
+++ trunk/gs/src/gxshade4.h	2007-05-09 15:45:54 UTC (rev 7936)
@@ -130,6 +130,7 @@
     int wedge_vertex_list_elem_count;
     int wedge_vertex_list_elem_count_max;
     gs_client_color color_domain;
+    fixed decomposition_limit;
     fixed fixed_flat;
     double smoothness;
     bool maybe_self_intersecting;

Modified: trunk/gs/src/gxshade6.c
===================================================================
--- trunk/gs/src/gxshade6.c	2007-05-09 11:34:33 UTC (rev 7935)
+++ trunk/gs/src/gxshade6.c	2007-05-09 15:45:54 UTC (rev 7936)
@@ -218,6 +218,8 @@
     pfs->linear_color = false;
     pfs->inside = false;
     pfs->n_color_args = 1;
+    pfs->decomposition_limit = float2fixed(min(pfs->dev->HWResolution[0], 
+					       pfs->dev->HWResolution[1]) / 72);
     pfs->fixed_flat = float2fixed(pfs->pis->flatness);
     /* Restrict the pfs->smoothness with 1/min_linear_grades, because cs_is_linear
        can't provide a better precision due to the color
@@ -1134,7 +1136,7 @@
        based on fn_is_monotonic_proc_t is_monotonic, 
        which applies to intervals. */
     patch_interpolate_color(c, c0, c1, pfs, 0.5);
-    if (ytop - ybot < fixed_1 / 2) /* Prevent an infinite color decomposition. */
+    if (ytop - ybot < pfs->decomposition_limit) /* Prevent an infinite color decomposition. */
 	code = constant_color_trapezoid(pfs, le, re, ybot, ytop, swap_axes, c);
     else {  
 	bool monotonic_color_save = pfs->monotonic_color;
@@ -2463,7 +2465,10 @@
 	case 0: /* The area is filled. */
 	    goto out;
 	case 2: /* decompose to constant color areas */
-	    if (sd < fixed_1 * 4) {
+	    /* Halftoned devices may do with some bigger areas
+	       due to imprecise representation of a contone color. 
+	       So we multiply the decomposition limit by 4 for a faster rendering. */
+	    if (sd < pfs->decomposition_limit * 4) {
 		code = constant_color_triangle(pfs, p2, p0, p1);
 		goto out;
 	    }
@@ -2484,7 +2489,7 @@
 	    }
 	    break;
 	case 1: /* decompose to linear color areas */
-	    if (sd < fixed_1) {
+	    if (sd < pfs->decomposition_limit) {
 		code = constant_color_triangle(pfs, p2, p0, p1);
 		goto out;
 	    }
@@ -2954,9 +2959,9 @@
 	double size_u = max(max(d0001x, d1011x), max(d0001y, d1011y));
 	double size_v = max(max(d0010x, d0111x), max(d0010y, d0111y));
 
-	if (size_u > fixed_1)
+	if (size_u > pfs->decomposition_limit)
 	    is_big_u = true;
-	if (size_v > fixed_1)
+	if (size_v > pfs->decomposition_limit)
 	    is_big_v = true;
 	else if (!is_big_u)
 	    return (QUADRANGLES || !pfs->maybe_self_intersecting ? 
@@ -3434,7 +3439,7 @@
 }
 
 private inline bool
-is_curve_x_small(const gs_fixed_point *pole, int pole_step, fixed fixed_flat)
+is_curve_x_small(const patch_fill_state_t *pfs, const gs_fixed_point *pole, int pole_step, fixed fixed_flat)
 {   /* Is curve within a single pixel, or smaller than half pixel ? */
     fixed xmin0 = min(pole[0 * pole_step].x, pole[1 * pole_step].x);
     fixed xmin1 = min(pole[2 * pole_step].x, pole[3 * pole_step].x);
@@ -3443,13 +3448,13 @@
     fixed xmax1 = max(pole[2 * pole_step].x, pole[3 * pole_step].x);
     fixed xmax =  max(xmax0, xmax1);
 
-    if(xmax - xmin <= fixed_1)
+    if(xmax - xmin <= pfs->decomposition_limit)
 	return true;
     return false;	
 }
 
 private inline bool
-is_curve_y_small(const gs_fixed_point *pole, int pole_step, fixed fixed_flat)
+is_curve_y_small(const patch_fill_state_t *pfs, const gs_fixed_point *pole, int pole_step, fixed fixed_flat)
 {   /* Is curve within a single pixel, or smaller than half pixel ? */
     fixed ymin0 = min(pole[0 * pole_step].y, pole[1 * pole_step].y);
     fixed ymin1 = min(pole[2 * pole_step].y, pole[3 * pole_step].y);
@@ -3458,7 +3463,7 @@
     fixed ymax1 = max(pole[2 * pole_step].y, pole[3 * pole_step].y);
     fixed ymax =  max(ymax0, ymax1);
 
-    if (ymax - ymin <= fixed_1)
+    if (ymax - ymin <= pfs->decomposition_limit)
 	return true;
     return false;	
 }
@@ -3466,21 +3471,21 @@
 private inline bool
 is_patch_narrow(const patch_fill_state_t *pfs, const tensor_patch *p)
 {
-    if (!is_curve_x_small(&p->pole[0][0], 4, pfs->fixed_flat))
+    if (!is_curve_x_small(pfs, &p->pole[0][0], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_x_small(&p->pole[0][1], 4, pfs->fixed_flat))
+    if (!is_curve_x_small(pfs, &p->pole[0][1], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_x_small(&p->pole[0][2], 4, pfs->fixed_flat))
+    if (!is_curve_x_small(pfs, &p->pole[0][2], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_x_small(&p->pole[0][3], 4, pfs->fixed_flat))
+    if (!is_curve_x_small(pfs, &p->pole[0][3], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_y_small(&p->pole[0][0], 4, pfs->fixed_flat))
+    if (!is_curve_y_small(pfs, &p->pole[0][0], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_y_small(&p->pole[0][1], 4, pfs->fixed_flat))
+    if (!is_curve_y_small(pfs, &p->pole[0][1], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_y_small(&p->pole[0][2], 4, pfs->fixed_flat))
+    if (!is_curve_y_small(pfs, &p->pole[0][2], 4, pfs->fixed_flat))
 	return false;
-    if (!is_curve_y_small(&p->pole[0][3], 4, pfs->fixed_flat))
+    if (!is_curve_y_small(pfs, &p->pole[0][3], 4, pfs->fixed_flat))
 	return false;
     return true;
 }



More information about the gs-cvs mailing list