[gs-cvs] gs/src

Igor Melichev igor at ghostscript.com
Mon May 17 05:14:35 PDT 2004


Update of /cvs/ghostscript/gs/src
In directory casper:/tmp/cvs-serv17073/gs/src

Modified Files:
	gxshade6.c 
Log Message:
A new implementation of shadings, step 77 (release candidate).

DETAILS :

1. A bug in is_quadrangle_color_linear caused an indeterministic choice of subdivision.
2. Provided a better order of filling wedges.
3. Mesh padding now stronger follows the V-boundary of a patch.

EXPECTED DIFFERENCES :

"442-01.ps"
"446-01.ps"
"483-01.ps"
"483-05-fixed.ps"
"483-05.ps"
"Clarke Tate Manns Chinese.ai"
"gradmesh.ai"
"self-intersect2.ps"
"SmoothShading.pdf"
"STEUER-RollingMesh 1(linear).ai"
"STEUER-RollingMesh 2(radial).ai"
"STEUER-RollingMesh 3(Final).ai"


Index: gxshade6.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxshade6.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- a/gxshade6.c	13 May 2004 12:46:41 -0000	1.71
+++ b/gxshade6.c	17 May 2004 12:14:31 -0000	1.72
@@ -2897,22 +2897,34 @@
 }
 
 private inline bool
-is_quadrangle_color_linear(const patch_fill_state_t *pfs, const quadrangle_patch *p)
+is_quadrangle_color_linear(const patch_fill_state_t *pfs, const quadrangle_patch *p, bool *uv)
 {
     if (pfs->unlinear)
 	return true; /* Disable this check. */
-    if (!is_color_linear(pfs, &p->p[0][0]->c, &p->p[0][1]->c))
+    if (!is_color_linear(pfs, &p->p[0][0]->c, &p->p[0][1]->c)) {
+	*uv = true;
 	return false;
-    if (!is_color_linear(pfs, &p->p[1][0]->c, &p->p[1][1]->c))
+    }
+    if (!is_color_linear(pfs, &p->p[1][0]->c, &p->p[1][1]->c)) {
+	*uv = true;
 	return false;
-    if (!is_color_linear(pfs, &p->p[0][0]->c, &p->p[1][0]->c))
+    }
+    if (!is_color_linear(pfs, &p->p[0][0]->c, &p->p[1][0]->c)) {
+	*uv = false;
 	return false;
-    if (!is_color_linear(pfs, &p->p[0][1]->c, &p->p[1][1]->c))
+    }
+    if (!is_color_linear(pfs, &p->p[0][1]->c, &p->p[1][1]->c)) {
+	*uv = false;
 	return false;
-    if (!is_color_linear(pfs, &p->p[0][0]->c, &p->p[1][1]->c))
+    }
+    if (!is_color_linear(pfs, &p->p[0][0]->c, &p->p[1][1]->c)) {
+	*uv = true;
 	return false;
-    if (!is_color_linear(pfs, &p->p[0][1]->c, &p->p[1][0]->c))
+    }
+    if (!is_color_linear(pfs, &p->p[0][1]->c, &p->p[1][0]->c)) {
+	*uv = false;
 	return false;
+    }
     return true;
 }
 
@@ -3034,7 +3046,7 @@
 			    pfs->maybe_self_intersecting);
 	if (!pfs->monotonic_color)
 	    pfs->monotonic_color = is_quadrangle_color_monotonic(pfs, p, &color_u)
-				&& is_quadrangle_color_linear(pfs, p);
+				&& is_quadrangle_color_linear(pfs, p, &color_u);
 	if (!pfs->monotonic_color) {
 	    /* go to divide. */
 	} else switch(quadrangle_color_change(pfs, p, &color_u)) {
@@ -3252,10 +3264,20 @@
     code = fill_wedges(pfs, ku[0], kum, p->pole[0], 1, &p->c[0][0], &p->c[0][1], inpatch_wedge);
     if (code < 0)
 	return code;
-    code = fill_wedges(pfs, ku[3], kum, p->pole[3], 1, &p->c[1][0], &p->c[1][1], inpatch_wedge);
+    if (INTERPATCH_PADDING) {
+	vd_bar(p->pole[0][0].x, p->pole[0][0].y, p->pole[3][0].x, p->pole[3][0].y, 0, RGB(255, 0, 0));
+	code = mesh_padding(pfs, &p->pole[0][0], &p->pole[3][0], &p->c[0][0], &p->c[1][0]);
+	if (code < 0)
+	    return code;
+	vd_bar(p->pole[0][3].x, p->pole[0][3].y, p->pole[3][3].x, p->pole[3][3].y, 0, RGB(255, 0, 0));
+	code = mesh_padding(pfs, &p->pole[0][3], &p->pole[3][3], &p->c[0][1], &p->c[1][1]);
+	if (code < 0)
+	    return code;
+    }
+    code = decompose_stripe(pfs, p, kum);
     if (code < 0)
 	return code;
-    return decompose_stripe(pfs, p, kum);
+    return fill_wedges(pfs, ku[3], kum, p->pole[3], 1, &p->c[1][0], &p->c[1][1], inpatch_wedge);
 }
 
 private inline bool
@@ -3388,7 +3410,7 @@
 }
 
 private int 
-fill_patch(patch_fill_state_t *pfs, const tensor_patch *p, int kv)
+fill_patch(patch_fill_state_t *pfs, const tensor_patch *p, int kv, int kv0, int kv1)
 {
     if (kv <= 1 && (is_patch_narrow(pfs, p) || 
 	    ((pfs->monotonic_color || is_color_monotonic_by_v(pfs, p)) && 
@@ -3399,28 +3421,57 @@
 	return fill_stripe(pfs, p);
     } else {
 	tensor_patch s0, s1;
+        shading_vertex_t q0, q1, q2;
 	int code;
 
-	if (kv <= 1) {
-	    code = fill_wedges(pfs, 2, 1, &p->pole[0][0], 4, &p->c[0][0], &p->c[1][0], inpatch_wedge);
+	split_patch(pfs, &s0, &s1, p);
+#ifdef OFF
+	if (kv0 <= 1) {
+	    q0.p = s0.pole[0][0];
+	    q0.c = s0.c[0][0];
+	    q1.p = s1.pole[3][0];
+	    q1.c = s1.c[1][0];
+	    q2.p = s0.pole[3][0];
+	    q2.c = s0.c[1][0];
+	    code = fill_triangle_wedge(pfs, &q0, &q1, &q2);
 	    if (code < 0)
 		return code;
-	    code = fill_wedges(pfs, 2, 1, &p->pole[0][3], 4, &p->c[0][1], &p->c[1][1], inpatch_wedge);
+	}
+	if (kv1 <= 1) {
+	    q0.p = s0.pole[0][3];
+	    q0.c = s0.c[0][1];
+	    q1.p = s1.pole[3][3];
+	    q1.c = s1.c[1][1];
+	    q2.p = s0.pole[3][3];
+	    q2.c = s0.c[1][1];
+	    code = fill_triangle_wedge(pfs, &q0, &q1, &q2);
 	    if (code < 0)
 		return code;
-	} else {
-	    /* Nothing to do, because patch_fill processed wedges over kvm. */
-	    /* The wedges over kvm are not processed here,
-	       because with a non-monotonic curve it would cause 
-	       redundant filling of the wedge parts. 
-	       We prefer to consider such wedge as a poligon
-	       rather than a set of overlapping triangles. */
 	}
-	split_patch(pfs, &s0, &s1, p);
-	code = fill_patch(pfs, &s0, kv / 2);
+#endif
+	code = fill_patch(pfs, &s0, kv / 2, kv0 / 2, kv1 / 2);
 	if (code < 0)
 	    return code;
-	return fill_patch(pfs, &s1, kv / 2);
+	return fill_patch(pfs, &s1, kv / 2, kv0 / 2, kv1 / 2);
+	/* fixme : To privide the precise filling order, we must
+	   decompose left and right wedges into pieces by intersections
+	   with stripes, and fill each piece with its stripe.
+	   A lazy wedge list would be fine for storing 
+	   the necessary information.
+
+	   If the patch is created from a radial shading,
+	   the wedge color appears a constant, so the filling order
+	   isn't important. The order is important for other 
+	   self-overlapping patches, but the visible effect is 
+	   just a slight norrowing the patch (as its lower layer appears
+	   visible through the upper layer near the side). 
+	   This kind of dropout isn't harmful, because
+	   contacring self-overlapping patches are painted 
+	   one after one by definition, so that a side coverage break
+	   appears unavoidable by definition.
+
+	   Delaying this improvement because it is low important.
+	 */
     }
 }
 
@@ -3551,16 +3602,7 @@
 #   if NOFILL_TEST
 	dbg_nofill = false;
 #   endif
-    code = fill_wedges(pfs, kv[0], kvm, &p.pole[0][0], 4, &p.c[0][0], &p.c[1][0], 
-		interpatch_padding | inpatch_wedge);
-    if (code >= 0)
-	code = fill_wedges(pfs, kv[3], kvm, &p.pole[0][3], 4, &p.c[0][1], &p.c[1][1], 
-		interpatch_padding | inpatch_wedge);
-    if (code >= 0)
-	code = fill_wedges(pfs, ku[0], kum, p.pole[0], 1, &p.c[0][0], &p.c[0][1], 
-		interpatch_padding | inpatch_wedge);
-    if (code >= 0)
-	code = fill_wedges(pfs, ku[3], kum, p.pole[3], 1, &p.c[1][0], &p.c[1][1], 
+    code = fill_wedges(pfs, ku[0], kum, p.pole[0], 1, &p.c[0][0], &p.c[0][1], 
 		interpatch_padding | inpatch_wedge);
     if (code >= 0) {
 	/* We would like to apply iterations for enumerating the kvm curve parts,
@@ -3571,11 +3613,14 @@
 	   the rounding errors do not depend on the direction. */
 #	if NOFILL_TEST
 	    dbg_nofill = false;
-	    code = fill_patch(pfs, &p, kvm);
+	    code = fill_patch(pfs, &p, kvm, kv[0], kv[3]);
 	    dbg_nofill = true;
 #	endif
-	code = fill_patch(pfs, &p, kvm);
+	code = fill_patch(pfs, &p, kvm, kv[0], kv[3]);
     }
+    if (code >= 0)
+	code = fill_wedges(pfs, ku[3], kum, p.pole[3], 1, &p.c[1][0], &p.c[1][1], 
+		interpatch_padding | inpatch_wedge);
     return code;
 }
 



More information about the gs-cvs mailing list