[gs-cvs] rev 7464 - in trunk/gs: doc src

leonardo at ghostscript.com leonardo at ghostscript.com
Thu Dec 7 18:22:37 PST 2006


Author: leonardo
Date: 2006-12-07 18:22:36 -0800 (Thu, 07 Dec 2006)
New Revision: 7464

Modified:
   trunk/gs/doc/pscet_status.txt
   trunk/gs/src/gxstroke.c
Log:
Fix (stroking) : The CPSI compatibility about the strokepath starting point.

DETAILS :

Debugged with CET 11-21.PS page 10.

PLRM doesn't specify a starting point for strokepath result.
Now we choose same point as CPSI does.
It appears important if a further drawing depends on current point,
and/or when a dashing is applied to strokepath.

We don't keep the old algorithm because it is not useful.
Supporting two modes (the CPSI compatible mode and the GS native mode)
would be too complicated with no good reason.

EXPECTED DIFFERENCES :

"298-05.ps"
"321-05.ps"



Modified: trunk/gs/doc/pscet_status.txt
===================================================================
--- trunk/gs/doc/pscet_status.txt	2006-12-08 00:31:05 UTC (rev 7463)
+++ trunk/gs/doc/pscet_status.txt	2006-12-08 02:22:36 UTC (rev 7464)
@@ -1845,17 +1845,13 @@
 11-21-1  DIFF?	Circle has small 'points' with CPSI -- Ghostscript is smooth.
                 assign: Raph.
 
-11-21-10  DIFF	positioning of 'O' and 'GT' wrong (see column 1)
-		The test executes "10 setlinewidth x 10 add y 10 add lineto strokepath".
-		(see GlobInterProc1).
-		It gives a rectangle rotated in 45 degrees.
-		However PLRM doesn't specify from which vertex
-		the path starts from.
-		Later 'O' and 'GT' are positioned at that vertex.
-		Our stroking algorithm is pretty complex,
-		so providing CPSI compatibility isn't simple.
-		Passing to Ray to decide what to do with it.
-		assign: Ray.
+11-21-10  AOK	Differences in look20, look30, look33 are caused by CPSI problem :
+		rlineto, rcurveto count wrong coordinates after strokepath.
+		It looks as the starting point for relative coordinate is not equal to
+		the current point. CPSI paints a self-intersecting curve with
+		"9 0 9 -9 0 -9 rcurveto stroke", which must not self-intersect.
+		A simplified test is placed to 
+		peeves:/home/igor/pscet/mytests/11-21-10-Igor01.ps 
 
 11-21-2  OK	Minor differences visually reviewed by RJJ
 
@@ -1863,10 +1859,9 @@
 
 11-21-4  DIFF	Analyzed by Igor.
 		There are several stroking problems.
-		1. The stroke starting point - same as 11-21-10.
-		2. linewidth - same as 11-09-4.
-		3. setflat - same as 09-09-1.
-		4. CPSI doesn't roll a dash pattern at some corners.
+		1. linewidth - same as 11-09-4.
+		2. setflat - same as 09-09-1.
+		3. CPSI doesn't roll a dash pattern at some corners.
 		An example is at the lower right corner of the page.
 		The dash at one corner looks longer than the distance to the corner.
 		IMO it's another CPSI bug.
@@ -1885,7 +1880,7 @@
 11-21-8  AOK	Device Dependent / Resolution Dependent. CPSI ignores setflat
 		Tek and CPSI differ.
 
-11-21-9  DIFF	similar to issues in 11-21-8 assign Raph. Tek and CPSI differ.
+11-21-9  AOK	similar to issues in 11-21-8. Tek and CPSI differ.
 
 11-22-1  DIFF	misplaced text graphics wrong assign: Igor
 
@@ -1994,17 +1989,17 @@
 
 11-28-1  OK	Minor differences visually reviewed by HAS
 
-11-28-10  DIFF	same as 11-21-8 assign: Raph
+11-28-10  AOK	same as 11-21-8.
 
-11-28-11  OK	fixed in r7228 - Raph
+11-28-11  AOK	same as 11-21-9.
 
-11-28-12  DIFF	same as 11-21-10 assign Ray
+11-28-12  AOK	same as 11-21-10.
 
 11-28-2  OK	Minor differences visually reviewed by HAS
 
 11-28-3  DIFF	Some elements are in the wrong place with GS. assign: Ray
 
-11-28-4  DIFF	paths differ assign: Igor
+11-28-4  AOK	CPSI stroking problem. CPSI and Tek differ.
 
 11-28-5  OK  	Fixed as of r7231.
 
@@ -2811,7 +2806,7 @@
 13-03-8  DIFF	gs has an extra 2 in column 1 and 7.  Squinting
                 x's overwrite o's row 1 col. 30 and a few other places
                 best to look at a digital diff.
-                assign Alex.
+                assign Igor.
 
 13-04-1  DIFF	Likely a CPSI problem. Analyzed by Igor.
                 Device dependent file
@@ -2887,7 +2882,7 @@
 
 13-12-4  DIFF	I don't know how to restore stack when the continuation
                 operator is used. - Alex
-                assign Raph
+                assign Peter
 
 13-12-5  OK	Minor differences visually reviewed by RJJ
 
@@ -3076,7 +3071,7 @@
 		location.  Different location of 'Script' in items 19, 20, and 25
 		in the 'CASH' column.  GS has 'cript' in item 13 in the 'MUCH'
 		column. - ADC
-                Assign: Ray.
+                Assign: Igor.
 
 13-23-1  DIFF	Extra line under /ordfeminine and /ordmasculine characters. - ADC
 	Might be a font issue: some fonts use underbars, others don't.
@@ -5090,15 +5085,15 @@
 
 31-01-4  OK	
 
-31-01-5  DIFF	Test 03 graphic incorrect assign Ray.
+31-01-5  DIFF	Test 03 graphic incorrect due to idioms. assign Alex.
 
 31-01-6  OK  	Fixed - Alex
 
 31-01-7  OK	Minor differences visually reviewed by RJJ
 
-31-01-8  DIFF	Test 03 and 07 wrong same as 31-01-5 assign Ray.
+31-01-8  DIFF	Test 03 and 07 wrong same as 31-01-5 assign Alex.
 
-31-01-9  DIFF	same as 31-01-8 assign Ray.
+31-01-9  DIFF	same as 31-01-8 assign Alex.
 
 31-02-1  DIFF	limitcheck vs. typecheck assign Ray
 
@@ -5120,7 +5115,9 @@
 
 31-06-2  OK	Minor differences in positions and character shapes - ADC
 
-31-07-1  OK	
+31-07-1  OK	Minor differences visually reviewed by Igor.
+		Note: This test draws different length line depending on timing
+		(number of loops depends on 'realtime' resolution and results).
 
 31-07-2  OK	
 

Modified: trunk/gs/src/gxstroke.c
===================================================================
--- trunk/gs/src/gxstroke.c	2006-12-08 00:31:05 UTC (rev 7463)
+++ trunk/gs/src/gxstroke.c	2006-12-08 02:22:36 UTC (rev 7464)
@@ -217,7 +217,7 @@
 private void compute_caps(pl_ptr);
 private int add_points(gx_path *, const gs_fixed_point *,
 		       int, bool);
-private int add_round_cap(gx_path *, const_ep_ptr);
+private int add_round_cap(gx_path *, const_ep_ptr, bool last_line);
 private int cap_points(gs_line_cap, const_ep_ptr,
 		       gs_fixed_point * /*[3] */ );
 
@@ -1140,9 +1140,8 @@
 {
     const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis);
     gs_fixed_point points[8];
-    int npoints;
+    int npoints = 0, initial_cap_points = 0;
     int code;
-    bool moveto_first = true;
 
     if (plp->thin) {
 	/* We didn't set up the endpoint parameters before, */
@@ -1151,49 +1150,71 @@
 	adjust_stroke(plp, pis, true, first == 0 && nplp == 0);
 	compute_caps(plp);
     }
-    /* Create an initial cap if desired. */
     if (first == 0 && pgs_lp->cap == gs_cap_round) {
-	vd_moveto(plp->o.co.x, plp->o.co.y);
-	if ((code = gx_path_add_point(ppath, plp->o.co.x, plp->o.co.y)) < 0 ||
-	    (code = add_round_cap(ppath, &plp->o)) < 0
-	    )
+	/* Initial moveto. */
+	code = gx_path_add_point(ppath, plp->o.ce.x, plp->o.ce.y);
+	if (code < 0)
 	    return code;
-	npoints = 0;
-	moveto_first = false;
+	vd_moveto(plp->o.ce.x, plp->o.ce.y);
     } else {
-	if ((npoints = cap_points((first == 0 ? pgs_lp->cap : gs_cap_butt), &plp->o, points)) < 0)
-	    return npoints;
+	/* With initial non-round cap the path must start with
+	   the cap's point for CPSI compatibility. So first compute
+	   the initial cap points and store them temporary at the end of array. */
+	int last_point_index; 
+
+	code = cap_points((first == 0 ? pgs_lp->cap : gs_cap_butt), &plp->o, points + 4);
+	if (code < 0)
+	    return code;
+	initial_cap_points = code;
+	last_point_index = 4 + initial_cap_points - 1;
+	/* Initial moveto. */
+	code = gx_path_add_point(ppath, points[last_point_index].x, points[last_point_index].y);
+	if (code < 0)
+	    return code;
+	vd_moveto(points[last_point_index].x, points[last_point_index].y);
     }
-    if (nplp == 0) {
-	/* Add a final cap. */
-	if (pgs_lp->cap == gs_cap_round) {
-	    ASSIGN_POINT(&points[npoints], plp->e.co);
-	    vd_lineto(points[npoints].x, points[npoints].y);
-	    ++npoints;
-	    if ((code = add_points(ppath, points, npoints, moveto_first)) < 0)
-		return code;
-	    code = add_round_cap(ppath, &plp->e);
-	    goto done;
-	}
-	code = cap_points(pgs_lp->cap, &plp->e, points + npoints);
-    } else if (join == gs_join_round) {
-	ASSIGN_POINT(&points[npoints], plp->e.co);
-	vd_lineto(points[npoints].x, points[npoints].y);
-	++npoints;
-	if ((code = add_points(ppath, points, npoints, moveto_first)) < 0)
+    /* The end cap. */
+    if ((nplp == 0 && pgs_lp->cap == gs_cap_round) || (nplp != 0 && join == gs_join_round)) {
+	/* The right side. */
+	code = gx_path_add_line(ppath, plp->e.co.x, plp->e.co.y);
+	if (code < 0)
 	    return code;
-	code = add_round_cap(ppath, &plp->e);
-	goto done;
+	vd_lineto(plp->e.co.x, plp->e.co.y);
+	/* The end cap. */
+	code = add_round_cap(ppath, &plp->e, true);
+    } else if (nplp == 0) {
+	code = cap_points(pgs_lp->cap, &plp->e, points);
     } else if (nplp->thin)	/* no join */
-	code = cap_points(gs_cap_butt, &plp->e, points + npoints);
+	code = cap_points(gs_cap_butt, &plp->e, points);
     else			/* non-round join */
 	code = line_join_points(pgs_lp, plp, nplp, points + npoints,
 				(uniform ? (gs_matrix *) 0 : &ctm_only(pis)),
 				join, reflected);
     if (code < 0)
 	return code;
-    code = add_points(ppath, points, npoints + code, moveto_first);
-  done:
+    npoints += code;
+    /* Create an initial cap if desired. */
+    if (first == 0 && pgs_lp->cap == gs_cap_round) {
+	/* Left side. */
+	ASSIGN_POINT(&points[npoints], plp->o.co);
+	npoints++;
+	vd_lineto(plp->e.co.x, plp->e.co.y);
+	code = add_points(ppath, points, npoints, false);
+	if (code < 0)
+	    return code;
+	/* The initial cap. */
+	/* Skip the last line because closepath below works instead it. */
+	code = add_round_cap(ppath, &plp->o, false);
+	if (code < 0)
+	    return code;
+	npoints = 0;
+    } else if (initial_cap_points > 1) {
+	/* Skip the last point because closepath below works instead it. */
+	if (npoints < 4)
+	    memcpy(points + npoints, points + 4, sizeof(*points) * (initial_cap_points - 1));
+	npoints += initial_cap_points - 1;
+    }
+    code = add_points(ppath, points, npoints, false);
     if (code < 0)
 	return code;
     vd_closepath;
@@ -1470,7 +1491,7 @@
 /* Add a round cap to a path. */
 /* Assume the current point is the cap origin (endp->co). */
 private int
-add_round_cap(gx_path * ppath, const_ep_ptr endp)
+add_round_cap(gx_path * ppath, const_ep_ptr endp, bool last_line)
 {
     int code;
 
@@ -1489,7 +1510,7 @@
 	(code = gx_path_add_partial_arc(ppath, xo, yo, xo - cdx, yo - cdy,
 					quarter_arc_fraction)) < 0 ||
 	/* The final point must be (xe,ye). */
-	(code = gx_path_add_line(ppath, xe, ye)) < 0
+	last_line && (code = gx_path_add_line(ppath, xe, ye)) < 0
 	)
 	return code;
     vd_lineto(xe, ye);



More information about the gs-cvs mailing list