shithub: freetype+ttf2subf

Download patch

ref: 666b11d59c61a2074172043ac3783b0620a7ae7b
parent: 6ac722b229a6ce58f61e7966bd069d870b333195
author: David Turner <[email protected]>
date: Thu Jul 27 11:59:08 EDT 2000

small fix to the auto-hinter:

the filling direction of each glyph is now re-computed on the
fly, given that we cannot rely on the "flags" field of the
source outline..

this fixes problems with many fonts, including the Arphic ones
(not to say that CJK fonts are handled better for now though..)

git/fs: mount .git/fs: mount/attach disallowed
--- a/src/autohint/ahglyph.c
+++ b/src/autohint/ahglyph.c
@@ -68,6 +68,134 @@
   }
 
 
+  /* this function is used by ah_get_orientation (see below) to test */
+  /* the fill direction of a given bbox extrema..                    */
+  static
+  int  ah_test_extrema( FT_Outline*  outline,
+                        int          n )
+  {
+    FT_Vector  *prev, *cur, *next;
+    FT_Pos      product;
+    FT_Int      first, last, c;
+
+
+    /* we need to compute the `previous' and `next' point */
+    /* for these 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 ? 2 : 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 is better to re-compute it directly (it seems that this flag   */
+  /* isn't correctly set for some weird composite glyphs currently).       */
+  /*                                                                       */
+  /* We do this by computing bounding box points, and computing their      */
+  /* curvature.                                                            */
+  /*                                                                       */
+  /* The function returns either 1 or -1.                                  */
+  /*                                                                       */
+  static
+  int  ah_get_orientation( FT_Outline*  outline )
+  {
+    FT_BBox  box;
+    FT_BBox  indices;
+    int      n, last;
+
+
+    indices.xMin = -1;
+    indices.yMin = -1;
+    indices.xMax = -1;
+    indices.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;
+        indices.xMin = n;
+      }
+      if ( x > box.xMax )
+      {
+        box.xMax     = x;
+        indices.xMax = n;
+      }
+
+      y = outline->points[n].y;
+      if ( y < box.yMin )
+      {
+        box.yMin     = y;
+        indices.yMin = n;
+      }
+      if ( y > box.yMax )
+      {
+        box.yMax     = y;
+        indices.yMax = n;
+      }
+    }
+
+    /* test orientation of the xmin */
+    n = ah_test_extrema( outline, indices.xMin );
+    if (n) goto Exit;
+    
+    n = ah_test_extrema( outline, indices.yMin );
+    if (n) goto Exit;
+    
+    n = ah_test_extrema( outline, indices.xMax );
+    if (n) goto Exit;
+    
+    n = ah_test_extrema( outline, indices.yMax );
+    if (!n)
+      n = 1;
+
+  Exit:
+    return n;    
+  }
+
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -218,6 +346,20 @@
     outline->num_hsegments = 0;
     outline->num_vsegments = 0;
 
+#if 1
+    /* we can't rely on the value of FT_Outline.flags to know the */
+    /* fill direction used for a glyph, given that some fonts are */
+    /* broken (e.g. the Arphic ones..). We thus recompute it each */
+    /* time we need to..                                          */
+    outline->vert_major_dir = ah_dir_up;
+    outline->horz_major_dir = ah_dir_left;
+
+    if ( ah_get_orientation( source ) > 1 )
+    {
+      outline->vert_major_dir = ah_dir_down;
+      outline->horz_major_dir = ah_dir_right;
+    }    
+#else
     /* Compute the vertical and horizontal major directions; this is     */
     /* currently done by inspecting the `ft_outline_reverse_fill' flag.  */
     /* However, some fonts have improper glyphs, and it'd be a good idea */
@@ -230,11 +372,13 @@
       outline->vert_major_dir = ah_dir_down;
       outline->horz_major_dir = ah_dir_right;
     }
-
+#endif
     outline->x_scale = face->size->metrics.x_scale;
     outline->y_scale = face->size->metrics.y_scale;
 
     points = outline->points;
+    if (outline->num_points == 0)
+      goto Exit;
 
     {
       /* do one thing at a time -- it is easier to understand, and */