Commit f3823281311eefb3b109289796cefee8ce9fac61

David Turner 2000-05-05T13:11:36

added experimental emboldening/outlining code. This is incomplete and will not compile so turned off

diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index c7ffe8c..248c386 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -498,3 +498,305 @@
         ;
     }
   }
+
+
+ /***************************************************************************/
+ /***************************************************************************/
+ /****                                                                   ****/
+ /****   EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT                      ****/
+ /****                                                                   ****/
+ /***************************************************************************/
+ /***************************************************************************/
+ 
+#if 0
+
+/* Compute the norm of a vector */
+#ifdef FT_CONFIG_OPTION_OLD_CALCS
+  static
+  FT_Pos   ft_norm( FT_Vector*  vec )
+  {
+	FT_Int64  t1, t2;
+
+	MUL_64( vec->x, vec->x, t1 );
+	MUL_64( vec->y, vec->y, t2 );
+	ADD_64( t1, t2, t1 );
+	return (FT_Pos)SQRT_64(t1);
+  }
+#else
+  static
+  FT_Pos  ft_norm( FT_Vector*  vec )
+  {
+    FT_F26Dot6  u, v, d;
+    FT_Int      shift;
+    FT_ULong    H, L, L2, hi, lo, med;
+
+    u = vec->x; if (u < 0) u = -u;
+    v = vec->y; if (v < 0) v = -v;
+
+    if (u < v)
+    {
+      d = u;
+      u = v;
+      v = d;
+    }
+
+    /* check that we're not trying to normalise zero !! */
+    if (u==0) return 0;
+
+    /* compute (u*u+v*v) on 64 bits with two 32-bit registers [H:L] */
+    hi  = (FT_ULong)u >> 16;
+    lo  = (FT_ULong)u & 0xFFFF;
+    med = hi*lo;
+    
+    H     = hi*hi + (med >> 15);
+    med <<= 17;
+    L     = lo*lo + med;
+    if (L < med) H++;
+    
+    hi  = (FT_ULong)v >> 16;
+    lo  = (FT_ULong)v & 0xFFFF;
+    med = hi*lo;
+    
+    H    += hi*hi + (med >> 15);
+    med <<= 17;
+    L2    = lo*lo + med;
+    if (L2 < med) H++;
+    
+    L += L2;
+    if (L < L2) H++;
+
+    /* if the value is smaller than 32-bits */
+    shift = 0;
+    if (H == 0)
+    {
+      while ((L & 0xC0000000) == 0)
+      {
+        L <<= 2;
+        shift++;
+      }
+      return (FT_Sqrt32(L) >> shift);
+    }
+    else
+    {
+      while (H)
+      {
+        L   = (L >> 2) | (H << 30);
+        H >>= 2;
+        shift++;
+      }
+      return (FT_Sqrt32(L) << shift);
+    }
+  }
+#endif
+
+  static
+  int  ft_test_extrema( FT_Outline*  outline,
+                        int          n )
+  {
+	FT_Vector  *prev, *cur, *next;
+	FT_Pos      product;
+    FT_Int      first, last;
+
+    /* we need to compute the "previous" and "next" point */
+    /* for this extrema..                                 */
+	cur   = outline->points + n;
+    prev  = cur - 1;
+    next  = cur + 1;
+
+    first = 0;    
+    for ( c = 0; c < outline->n_contours; c++ )
+    {
+      last  = outline->contours[c];
+
+      if ( n == first )
+        prev = outline->points + last;
+        
+      if ( n == last )
+        next = outline->points + first;
+        
+      first = last + 1;
+    }
+
+	product = FT_MulDiv( cur->x - prev->x,   /* in.x  */
+                         next->y - cur->y,   /* out.y */
+                         0x40 ) -
+
+              FT_MulDiv( cur->y - prev->y,   /* in.y  */
+                         next->x - cur->x,   /* out.x */
+                         0x40 );
+
+	if (product)
+		product = ( product > 0 ? 1 : -1 );
+
+	return product;
+  }
+
+
+/* Compute the orientation of path filling. It differs between TrueType   */
+/* and Type1 formats. We could use the 'ft_outline_reverse_fill' flag,    */
+/* but it's better to re-compute it directly (it seems that this flag     */
+/* isn't correctly set for some weird composite glyphs for now)..         */
+/*                                                                        */
+/* We do this by computing bounding box points, and computing their       */
+/* curvature.. the function returns either 1 or -1                        */
+/*                                                                        */
+  static
+  int  ft_get_orientation( FT_Outline*  outline )
+  {
+	FT_BBox    box;
+	FT_BBox    indexes;
+	int	       n, last;
+
+	indexes.xMin = -1;
+	indexes.yMin = -1;
+	indexes.xMax = -1;
+	indexes.yMax = -1;
+
+	box.xMin = box.yMin = 32767;
+	box.xMax = box.yMax = -32768;
+
+	/* is it empty ? */
+	if ( outline->n_contours < 1 )
+	  return 1;
+
+	last = outline->contours[outline->n_contours-1];
+
+	for ( n = 0; n <= last; n++ )
+	{
+	  FT_Pos  x, y;
+
+	  x = outline->points[n].x;
+	  if ( x < box.xMin )
+	  {
+		box.xMin     = x;
+		indexes.xMin = n;
+	  }
+
+	  if ( x > box.xMax )
+	  {
+		box.xMax     = x;
+		indexes.xMax = n;
+	  }
+
+	  y = outline->points[n].y;
+	  if ( y < box.yMin )
+	  {
+		box.yMin     = y;
+		indexes.yMin = n;
+	  }
+
+	  if ( y > box.yMax )
+	  {
+		box.yMax     = y;
+		indexes.yMax = n;
+	  }
+	}
+
+	/* test orientation of the xmin */
+	return ft_test_extrema( outline, indexes.xMin ) ||
+           ft_test_extrema( outline, indexes.yMin ) ||
+           ft_test_extrema( outline, indexes.xMax ) ||
+           ft_test_extrema( outline, indexes.yMax ) ||
+           1;  /* this is an empty glyph ?? */
+  }
+
+
+  static
+  FT_Error  ft_embolden( FT_Face       original,
+                         FT_Outline*   outline,
+                         FT_Pos*       advance )
+  {
+	FT_Vector  u, v;
+	FT_Vector* points;
+	FT_Vector  cur, prev, next;
+	FT_Pos     distance;
+	int        c, n, first, orientation;
+
+	(void)advance;
+
+	/* compute control distance */
+	distance = FT_MulFix( original->em_size/60,
+						  original->size->metrics.y_scale );
+
+	orientation = ft_get_orientation( &original->glyph->outline );
+
+	points = original->glyph->outline.points;
+
+	first = 0;
+	for ( c = 0; c < outline->n_contours; c++ )
+	{
+	  int  last = outline->contours[c];
+	  
+	  prev = points[last];
+
+	  for ( n = first; n <= last; n++ )
+	  {
+		FT_Pos     norme, delta, d;
+		FT_Vector  in, out;
+
+		cur = points[n];
+		if ( n < last ) next = points[n+1];
+		           else next = points[first];
+
+		/* compute the in and out vectors */
+		in.x  = cur.x - prev.x;
+		in.y  = cur.y - prev.y;
+
+		out.x = next.x - cur.x;
+		out.y = next.y - cur.y;
+
+		/* compute U and V */
+		norme = ft_norm( &in );
+		u.x   = orientation *   FT_DivFix( in.y, norme );
+		u.y   = orientation * - FT_DivFix( in.x, norme );
+
+		norme = ft_norm( &out );
+		v.x   = orientation *   FT_DivFix( out.y, norme );
+		v.y   = orientation * - FT_DivFix( out.x, norme );
+
+		d = distance;
+
+		if ( (outline->flags[n] & FT_Curve_Tag_On) == 0 )
+			d *= 2;
+
+		/* Check discriminant for parallel vectors */
+		delta = FT_MulFix( u.x, v.y ) - FT_MulFix( u.y, v.x );
+		if ( delta > FT_BOLD_THRESHOLD || delta < - FT_BOLD_THRESHOLD )
+		{
+		  /* Move point - compute A and B */
+	      FT_Pos  x, y, A, B;
+
+		  A = d + FT_MulFix( cur.x, u.x ) + FT_MulFix( cur.y, u.y );
+		  B = d + FT_MulFix( cur.x, v.x ) + FT_MulFix( cur.y, v.y );
+
+		  x = FT_MulFix( A, v.y ) - FT_MulFix( B, u.y );
+		  y = FT_MulFix( B, u.x ) - FT_MulFix( A, v.x );
+
+		  outline->points[n].x = distance + FT_DivFix( x, delta );
+		  outline->points[n].y = distance + FT_DivFix( y, delta );
+		}
+		else
+		{
+		  /* Vectors are nearly parallel */
+		  FT_Pos  x, y;
+
+		  x = distance + cur.x + FT_MulFix( d, u.x + v.x )/2;
+		  y = distance + cur.y + FT_MulFix( d, u.y + v.y )/2;
+		  
+		  outline->points[n].x = x;
+		  outline->points[n].y = y;
+		}
+
+		prev = cur;
+	  }
+
+	  first = last+1;
+	}
+
+    if (advance)
+      *advance = (*advance + distance*4) & -64;
+
+	return 0;
+  }
+
+#endif /* 0 - EXPERIMENTAL STUFF !! */