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

leonardo at ghostscript.com leonardo at ghostscript.com
Tue Jan 9 10:36:49 PST 2007


Author: leonardo
Date: 2007-01-09 10:36:48 -0800 (Tue, 09 Jan 2007)
New Revision: 7589

Modified:
   trunk/gs/src/gsmisc.c
   trunk/gs/src/gxfixed.h
   trunk/gs/src/gxshade6.c
   trunk/gs/src/lib.mak
Log:
Type 1 hinter : Implementing a contour sign normalization, part 3.

DETAILS :

This is continuation of the preparation for fixing the bug 688947  
"Ghostscript renders font incorrectly (letter 'o' filled in)".

This change is algorithmically equivalent.
It factors out gx_intersect_small_bars from the shading code.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/src/gsmisc.c
===================================================================
--- trunk/gs/src/gsmisc.c	2007-01-09 14:19:27 UTC (rev 7588)
+++ trunk/gs/src/gsmisc.c	2007-01-09 18:36:48 UTC (rev 7589)
@@ -55,6 +55,7 @@
 #include "gconfigv.h"		/* for USE_ASM */
 #include "gxfarith.h"
 #include "gxfixed.h"
+#include "stdint_.h"
 
 /* ------ Redirected stdout and stderr  ------ */
 
@@ -1285,3 +1286,113 @@
     }
     return 0;
 }
+
+/*
+ * Define a function for finding intersection of small bars.
+ * Coordinates must be so small that their cubes fit into 60 bits.
+ * This function doesn't check intersections at end of bars,
+ * so  the caller must care of them on necessity.
+ * Returns : *ry is the Y-coordinate of the intersection
+ * truncated to 'fixed'; *ey is 1 iff the precise Y coordinate of
+ * the intersection is greater than *ry (used by the shading algorithm).
+ */
+bool 
+gx_intersect_small_bars(fixed q0x, fixed q0y, fixed q1x, fixed q1y, fixed q2x, fixed q2y, 
+			fixed q3x, fixed q3y, fixed *ry, fixed *ey)
+{
+    fixed dx1 = q1x - q0x, dy1 = q1y - q0y;
+    fixed dx2 = q2x - q0x, dy2 = q2y - q0y;
+    fixed dx3 = q3x - q0x, dy3 = q3y - q0y;
+
+    int64_t vp2a, vp2b, vp3a, vp3b;
+    int s2, s3;
+
+    if (dx1 == 0 && dy1 == 0)
+	return false; /* Zero length bars are out of interest. */
+    if (dx2 == 0 && dy2 == 0)
+	return false; /* Contacting ends are out of interest. */
+    if (dx3 == 0 && dy3 == 0)
+	return false; /* Contacting ends are out of interest. */
+    if (dx2 == dx1 && dy2 == dy1)
+	return false; /* Contacting ends are out of interest. */
+    if (dx3 == dx1 && dy3 == dy1)
+	return false; /* Contacting ends are out of interest. */
+    if (dx2 == dx3 && dy2 == dy3)
+	return false; /* Zero length bars are out of interest. */
+    vp2a = (int64_t)dx1 * dy2;
+    vp2b = (int64_t)dy1 * dx2; 
+    /* vp2 = vp2a - vp2b; It can overflow int64_t, but we only need the sign. */
+    if (vp2a > vp2b)
+	s2 = 1;
+    else if (vp2a < vp2b)
+	s2 = -1;
+    else 
+	s2 = 0;
+    vp3a = (int64_t)dx1 * dy3;
+    vp3b = (int64_t)dy1 * dx3; 
+    /* vp3 = vp3a - vp3b; It can overflow int64_t, but we only need the sign. */
+    if (vp3a > vp3b)
+	s3 = 1;
+    else if (vp3a < vp3b)
+	s3 = -1;
+    else 
+	s3 = 0;
+    if (s2 == 0) {
+	if (s3 == 0)
+	    return false; /* Collinear bars - out of interest. */
+	if (0 <= dx2 && dx2 <= dx1 && 0 <= dy2 && dy2 <= dy1) {
+	    /* The start of the bar 2 is in the bar 1. */
+	    *ry = q2y;
+	    *ey = 0;
+	    return true;
+	}
+    } else if (s3 == 0) {
+	if (0 <= dx3 && dx3 <= dx1 && 0 <= dy3 && dy3 <= dy1) {
+	    /* The end of the bar 2 is in the bar 1. */
+	    *ry = q3y;
+	    *ey = 0;
+	    return true;
+	}
+    } else if (s2 * s3 < 0) {
+	/* The intersection definitely exists, so the determinant isn't zero.  */
+	fixed d23x = dx3 - dx2, d23y = dy3 - dy2;
+	int64_t det = (int64_t)dx1 * d23y - (int64_t)dy1 * d23x;
+	int64_t mul = (int64_t)dx2 * d23y - (int64_t)dy2 * d23x;
+	{
+	    /* Assuming small bars : cubes of coordinates must fit into int64_t.
+	       curve_samples must provide that.  */
+	    int64_t num = dy1 * mul, iiy;
+	    fixed iy;
+	    fixed pry, pey;
+
+	    {	/* Likely when called form wedge_trap_decompose or constant_color_quadrangle,
+		   we always have det > 0 && num >= 0, but we check here for a safety reason. */
+		if (det < 0)
+		    num = -num, det = -det;
+		iiy = (num >= 0 ? num / det : (num - det + 1) / det);
+		iy = (fixed)iiy;
+		if (iy != iiy) {
+		    /* If it is inside the bars, it must fit into fixed. */
+		    return false;
+		}
+	    }
+	    if (dy1 > 0 && iy >= dy1)
+		return false; /* Outside the bar 1. */
+	    if (dy1 < 0 && iy <= dy1)
+		return false; /* Outside the bar 1. */
+	    if (dy2 < dy3) {
+		if (iy <= dy2 || iy >= dy3)
+		    return false; /* Outside the bar 2. */
+	    } else {
+		if (iy >= dy2 || iy <= dy3)
+		    return false; /* Outside the bar 2. */
+	    }
+	    pry = q0y + (fixed)iy;
+	    pey = (iy * det < num ? 1 : 0);
+	    *ry = pry;
+	    *ey = pey;
+	}
+	return true;
+    }
+    return false;
+}

Modified: trunk/gs/src/gxfixed.h
===================================================================
--- trunk/gs/src/gxfixed.h	2007-01-09 14:19:27 UTC (rev 7588)
+++ trunk/gs/src/gxfixed.h	2007-01-09 18:36:48 UTC (rev 7589)
@@ -168,6 +168,19 @@
  */
 
 /*
+ * Define a function for finding intersection of small bars.
+ * Coordinates must be so small that their cubes fit into 60 bits.
+ * This function doesn't check intersections at end of bars,
+ * so  the caller must care of them on necessity.
+ * Returns : *ry is the Y-coordinate of the intersection
+ * truncated to 'fixed'; *ey is 1 iff the precise Y coordinate of
+ * the intersection is greater than *ry (used by the shading algorithm).
+ */
+bool 
+gx_intersect_small_bars(fixed q0x, fixed q0y, fixed q1x, fixed q1y, fixed q2x, fixed q2y, 
+			fixed q3x, fixed q3y, fixed *ry, fixed *ey);
+
+/*
  * The macros all use R for the (fixed) result, FB for the second (float)
  * operand, and dtemp for a temporary double variable.  The work is divided
  * between the two macros of each set in order to avoid bogus "possibly

Modified: trunk/gs/src/gxshade6.c
===================================================================
--- trunk/gs/src/gxshade6.c	2007-01-09 14:19:27 UTC (rev 7588)
+++ trunk/gs/src/gxshade6.c	2007-01-09 18:36:48 UTC (rev 7589)
@@ -781,104 +781,11 @@
     return 1 << k;
 }
 
-private bool 
+private inline bool
 intersection_of_small_bars(const gs_fixed_point q[4], int i0, int i1, int i2, int i3, fixed *ry, fixed *ey)
 {
     /* This function is only used with QUADRANGLES. */
-    fixed dx1 = q[i1].x - q[i0].x, dy1 = q[i1].y - q[i0].y;
-    fixed dx2 = q[i2].x - q[i0].x, dy2 = q[i2].y - q[i0].y;
-    fixed dx3 = q[i3].x - q[i0].x, dy3 = q[i3].y - q[i0].y;
-    int64_t vp2a, vp2b, vp3a, vp3b;
-    int s2, s3;
-
-    if (dx1 == 0 && dy1 == 0)
-	return false; /* Zero length bars are out of interest. */
-    if (dx2 == 0 && dy2 == 0)
-	return false; /* Contacting ends are out of interest. */
-    if (dx3 == 0 && dy3 == 0)
-	return false; /* Contacting ends are out of interest. */
-    if (dx2 == dx1 && dy2 == dy1)
-	return false; /* Contacting ends are out of interest. */
-    if (dx3 == dx1 && dy3 == dy1)
-	return false; /* Contacting ends are out of interest. */
-    if (dx2 == dx3 && dy2 == dy3)
-	return false; /* Zero length bars are out of interest. */
-    vp2a = (int64_t)dx1 * dy2;
-    vp2b = (int64_t)dy1 * dx2; 
-    /* vp2 = vp2a - vp2b; It can overflow int64_t, but we only need the sign. */
-    if (vp2a > vp2b)
-	s2 = 1;
-    else if (vp2a < vp2b)
-	s2 = -1;
-    else 
-	s2 = 0;
-    vp3a = (int64_t)dx1 * dy3;
-    vp3b = (int64_t)dy1 * dx3; 
-    /* vp3 = vp3a - vp3b; It can overflow int64_t, but we only need the sign. */
-    if (vp3a > vp3b)
-	s3 = 1;
-    else if (vp3a < vp3b)
-	s3 = -1;
-    else 
-	s3 = 0;
-    if (s2 == 0) {
-	if (s3 == 0)
-	    return false; /* Collinear bars - out of interest. */
-	if (0 <= dx2 && dx2 <= dx1 && 0 <= dy2 && dy2 <= dy1) {
-	    /* The start of the bar 2 is in the bar 1. */
-	    *ry = q[i2].y;
-	    *ey = 0;
-	    return true;
-	}
-    } else if (s3 == 0) {
-	if (0 <= dx3 && dx3 <= dx1 && 0 <= dy3 && dy3 <= dy1) {
-	    /* The end of the bar 2 is in the bar 1. */
-	    *ry = q[i3].y;
-	    *ey = 0;
-	    return true;
-	}
-    } else if (s2 * s3 < 0) {
-	/* The intersection definitely exists, so the determinant isn't zero.  */
-	fixed d23x = dx3 - dx2, d23y = dy3 - dy2;
-	int64_t det = (int64_t)dx1 * d23y - (int64_t)dy1 * d23x;
-	int64_t mul = (int64_t)dx2 * d23y - (int64_t)dy2 * d23x;
-	{
-	    /* Assuming small bars : cubes of coordinates must fit into int64_t.
-	       curve_samples must provide that.  */
-	    int64_t num = dy1 * mul, iiy;
-	    fixed iy;
-	    fixed pry, pey;
-
-	    {	/* Likely when called form wedge_trap_decompose or constant_color_quadrangle,
-		   we always have det > 0 && num >= 0, but we check here for a safety reason. */
-		if (det < 0)
-		    num = -num, det = -det;
-		iiy = (num >= 0 ? num / det : (num - det + 1) / det);
-		iy = (fixed)iiy;
-		if (iy != iiy) {
-		    /* If it is inside the bars, it must fit into fixed. */
-		    return false;
-		}
-	    }
-	    if (dy1 > 0 && iy >= dy1)
-		return false; /* Outside the bar 1. */
-	    if (dy1 < 0 && iy <= dy1)
-		return false; /* Outside the bar 1. */
-	    if (dy2 < dy3) {
-		if (iy <= dy2 || iy >= dy3)
-		    return false; /* Outside the bar 2. */
-	    } else {
-		if (iy >= dy2 || iy <= dy3)
-		    return false; /* Outside the bar 2. */
-	    }
-	    pry = q[i0].y + (fixed)iy;
-	    pey = (iy * det < num ? 1 : 0);
-	    *ry = pry;
-	    *ey = pey;
-	}
-	return true;
-    }
-    return false;
+    return gx_intersect_small_bars(q[i0].x, q[i0].y, q[i1].x, q[i1].y, q[i2].x, q[i2].y, q[i3].x, q[i3].y, ry, ey);
 }
 
 private inline void

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2007-01-09 14:19:27 UTC (rev 7588)
+++ trunk/gs/src/lib.mak	2007-01-09 18:36:48 UTC (rev 7589)
@@ -252,7 +252,7 @@
 $(GLOBJ)gsmisc.$(OBJ) : $(GLSRC)gsmisc.c $(GXERR)\
  $(gconfigv_h) $(std_h) $(vmsmath_h)\
  $(ctype__h) $(malloc__h) $(math__h) $(memory__h) $(string__h)\
- $(gpcheck_h) $(gserror_h) $(gxfarith_h) $(gxfixed_h)
+ $(gpcheck_h) $(gserror_h) $(gxfarith_h) $(gxfixed_h) $(stdint__h)
 	$(GLCC) $(GLO_)gsmisc.$(OBJ) $(C_) $(GLSRC)gsmisc.c
 
 $(GLOBJ)gslibctx.$(OBJ) : $(GLSRC)gslibctx.c  $(GXERR)\



More information about the gs-cvs mailing list