shithub: freetype+ttf2subf

Download patch

ref: 66cb4790bfc5146158a388c6cc9ab2cc40dcf6fb
parent: 6059b0317ed62e7f132373c217bce514b95f85e8
author: David Turner <[email protected]>
date: Mon May 14 10:04:23 EDT 2001

* src/base/ftcalc.c (FT_DivFix): fixed a bug in the 64-bit code that
    created incorrect scale factors !!

    * src/autohint/ahglobal.c, src/autohint/ahglyph.c, src/autohint/ahhint.c:
    fixed the incorrect blue zone computations, and improved the composite
    support. Note that these changes result in improved rendering, while
    sometimes introducing their own artefacts. That's probably the last
    big change to the autohinter before the introduction of its complete
    replacement..

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2001-05-14  David Turner  <[email protected]>
+
+    * src/base/ftcalc.c (FT_DivFix): fixed a bug in the 64-bit code that
+    created incorrect scale factors !!
+
+    * src/autohint/ahglobal.c, src/autohint/ahglyph.c, src/autohint/ahhint.c:
+    fixed the incorrect blue zone computations, and improved the composite
+    support. Note that these changes result in improved rendering, while
+    sometimes introducing their own artefacts. That's probably the last
+    big change to the autohinter before the introduction of its complete
+    replacement..
+
 2001-05-12  Werner Lemberg  <[email protected]>
 
 	* include/freetype/ftbbox.h: FTBBOX_H -> __FTBBOX_H__.
--- a/src/autohint/ahglobal.c
+++ b/src/autohint/ahglobal.c
@@ -47,7 +47,7 @@
 
     for ( i = 1; i < count; i++ )
     {
-      for ( j = i; j > 1; j-- )
+      for ( j = i; j > 0; j-- )
       {
         if ( table[j] > table[j - 1] )
           break;
--- a/src/autohint/ahglyph.c
+++ b/src/autohint/ahglyph.c
@@ -28,9 +28,111 @@
 #include <stdio.h>
 
 
-#define xxxAH_DEBUG_GLYPH
 
+#ifdef AH_DEBUG
 
+  void  ah_dump_edges( AH_Outline*  outline )
+  {
+    AH_Edge*     edges;
+    AH_Edge*     edge_limit;
+    AH_Segment*  segments;
+    FT_Int       dimension;
+
+
+    edges      = outline->horz_edges;
+    edge_limit = edges + outline->num_hedges;
+    segments   = outline->horz_segments;
+
+    for ( dimension = 1; dimension >= 0; dimension-- )
+    {
+      AH_Edge*  edge;
+
+
+      printf ( "Table of %s edges:\n",
+               !dimension ? "vertical" : "horizontal" );
+      printf ( "  [ index |  pos |  dir  | link |"
+               " serif | blue | opos  |  pos  ]\n" );
+
+      for ( edge = edges; edge < edge_limit; edge++ )
+      {
+        printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",
+                 edge - edges,
+                 (int)edge->fpos,
+                 edge->dir == ah_dir_up
+                   ? "up"
+                   : ( edge->dir == ah_dir_down
+                         ? "down"
+                         : ( edge->dir == ah_dir_left
+                               ? "left"
+                               : ( edge->dir == ah_dir_right
+                                     ? "right"
+                                     : "none" ) ) ),
+                 edge->link ? ( edge->link - edges ) : -1,
+                 edge->serif ? ( edge->serif - edges ) : -1,
+                 edge->blue_edge ? 'y' : 'n',
+                 edge->opos / 64.0,
+                 edge->pos / 64.0 );
+      }
+
+      edges      = outline->vert_edges;
+      edge_limit = edges + outline->num_vedges;
+      segments   = outline->vert_segments;
+    }
+  }
+
+
+  /* A function used to dump the array of linked segments */
+  void  ah_dump_segments( AH_Outline*  outline )
+  {
+    AH_Segment*  segments;
+    AH_Segment*  segment_limit;
+    AH_Point*    points;
+    FT_Int       dimension;
+
+
+    points        = outline->points;
+    segments      = outline->horz_segments;
+    segment_limit = segments + outline->num_hsegments;
+
+    for ( dimension = 1; dimension >= 0; dimension-- )
+    {
+      AH_Segment*  seg;
+
+
+      printf ( "Table of %s segments:\n",
+               !dimension ? "vertical" : "horizontal" );
+      printf ( "  [ index |  pos |  dir  | link | serif |"
+               " numl | first | start ]\n" );
+
+      for ( seg = segments; seg < segment_limit; seg++ )
+      {
+        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
+                 seg - segments,
+                 (int)seg->pos,
+                 seg->dir == ah_dir_up
+                   ? "up"
+                   : ( seg->dir == ah_dir_down
+                         ? "down"
+                         : ( seg->dir == ah_dir_left
+                               ? "left"
+                               : ( seg->dir == ah_dir_right
+                                     ? "right"
+                                     : "none" ) ) ),
+                 seg->link ? (seg->link-segments) : -1,
+                 seg->serif ? (seg->serif-segments) : -1,
+                 (int)seg->num_linked,
+                 seg->first - points,
+                 seg->last - points );
+      }
+
+      segments      = outline->vert_segments;
+      segment_limit = segments + outline->num_vsegments;
+    }
+  }
+
+#endif /* AH_DEBUG */
+
+
   /* compute the direction value of a given vector.. */
   static
   AH_Direction  ah_compute_direction( FT_Pos  dx,
@@ -344,8 +446,6 @@
     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.       */
@@ -359,23 +459,6 @@
       outline->horz_major_dir = ah_dir_right;
     }
 
-#else  /* !1 */
-
-    /* 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 */
-    /* to be able to re-compute these values on the fly.                 */
-    outline->vert_major_dir = ah_dir_up;
-    outline->horz_major_dir = ah_dir_left;
-
-    if ( source->flags & ft_outline_reverse_fill )
-    {
-      outline->vert_major_dir = ah_dir_down;
-      outline->horz_major_dir = ah_dir_right;
-    }
-
-#endif /* !1 */
-
     outline->x_scale = face->size->metrics.x_scale;
     outline->y_scale = face->size->metrics.y_scale;
 
@@ -952,60 +1035,7 @@
   }
 
 
-#ifdef AH_DEBUG_GLYPH
 
-  /* A function used to dump the array of linked segments */
-  void  ah_dump_segments( AH_Outline*  outline )
-  {
-    AH_Segment*  segments;
-    AH_Segment*  segment_limit;
-    AH_Point*    points;
-    FT_Int       dimension;
-
-
-    points        = outline->points;
-    segments      = outline->horz_segments;
-    segment_limit = segments + outline->num_hsegments;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AH_Segment*  seg;
-
-
-      printf ( "Table of %s segments:\n",
-               !dimension ? "vertical" : "horizontal" );
-      printf ( "  [ index |  pos |  dir  | link | serif |"
-               " numl | first | start ]\n" );
-
-      for ( seg = segments; seg < segment_limit; seg++ )
-      {
-        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
-                 seg - segments,
-                 (int)seg->pos,
-                 seg->dir == ah_dir_up
-                   ? "up"
-                   : ( seg->dir == ah_dir_down
-                         ? "down"
-                         : ( seg->dir == ah_dir_left
-                               ? "left"
-                               : ( seg->dir == ah_dir_right
-                                     ? "right"
-                                     : "none" ) ) ),
-                 seg->link ? (seg->link-segments) : -1,
-                 seg->serif ? (seg->serif-segments) : -1,
-                 (int)seg->num_linked,
-                 seg->first - points,
-                 seg->last - points );
-      }
-
-      segments      = outline->vert_segments;
-      segment_limit = segments + outline->num_vsegments;
-    }
-  }
-
-#endif /* AH_DEBUG_GLYPH */
-
-
   static
   void  ah_outline_compute_edges( AH_Outline*  outline )
   {
@@ -1218,7 +1248,7 @@
         /* set the round/straight flags */
         edge->flags = ah_edge_normal;
 
-        if ( is_straight == 0 && is_round )
+        if ( is_round > 0 && is_round >= is_straight )
           edge->flags |= ah_edge_round;
 
         /* set the edge's main direction */
@@ -1286,7 +1316,39 @@
     AH_Globals*  globals    = &face_globals->design;
     FT_Fixed     y_scale    = outline->y_scale;
 
+    FT_Bool      blue_active[ ah_blue_max ];
 
+
+    /* compute which blue zones are active, i.e. have their scaled */
+    /* size < 3/4 pixels                                           */
+    {
+      AH_Blue  blue;
+      FT_Bool  check = 0;
+
+      for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ )
+      {
+        FT_Pos  ref, shoot, dist;
+
+        ref   = globals->blue_refs[blue];
+        shoot = globals->blue_shoots[blue];
+        dist  = ref-shoot;
+        if (dist < 0)
+          dist = -dist;
+
+        blue_active[blue] = 0;
+
+        if ( FT_MulFix( dist, y_scale ) < 48 )
+        {
+          blue_active[blue] = 1;
+          check = 1;
+        }
+      }
+
+      /* return immediately if no blue zone is active */
+      if (!check)
+        return;
+    }
+
     /* compute for each horizontal edge, which blue zone is closer */
     for ( ; edge < edge_limit; edge++ )
     {
@@ -1309,6 +1371,8 @@
         FT_Bool  is_top_blue  = AH_IS_TOP_BLUE( blue );
         FT_Bool  is_major_dir = edge->dir == outline->horz_major_dir;
 
+        if ( !blue_active[blue] )
+          continue;
 
         /* if it is a top zone, the edge must be against the major    */
         /* direction; if it is a bottom zone, it must be in the major */
@@ -1392,58 +1456,6 @@
   }
 
 
-#ifdef AH_DEBUG_GLYPH
-
-  void  ah_dump_edges( AH_Outline*  outline )
-  {
-    AH_Edge*     edges;
-    AH_Edge*     edge_limit;
-    AH_Segment*  segments;
-    FT_Int       dimension;
-
-
-    edges      = outline->horz_edges;
-    edge_limit = edges + outline->num_hedges;
-    segments   = outline->horz_segments;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AH_Edge*  edge;
-
-
-      printf ( "Table of %s edges:\n",
-               !dimension ? "vertical" : "horizontal" );
-      printf ( "  [ index |  pos |  dir  | link |"
-               " serif | blue | opos  |  pos  ]\n" );
-
-      for ( edge = edges; edge < edge_limit; edge++ )
-      {
-        printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",
-                 edge - edges,
-                 (int)edge->fpos,
-                 edge->dir == ah_dir_up
-                   ? "up"
-                   : ( edge->dir == ah_dir_down
-                         ? "down"
-                         : ( edge->dir == ah_dir_left
-                               ? "left"
-                               : ( edge->dir == ah_dir_right
-                                     ? "right"
-                                     : "none" ) ) ),
-                 edge->link ? ( edge->link - edges ) : -1,
-                 edge->serif ? ( edge->serif - edges ) : -1,
-                 edge->blue_edge ? 'y' : 'n',
-                 edge->opos / 64.0,
-                 edge->pos / 64.0 );
-      }
-
-      edges      = outline->vert_edges;
-      edge_limit = edges + outline->num_vedges;
-      segments   = outline->vert_segments;
-    }
-  }
-
-#endif /* AH_DEBUG_GLYPH */
 
 
 /* END */
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -1051,14 +1051,14 @@
     switch ( slot->format )
     {
     case ft_glyph_format_outline:
-    
+
       /* translate glyph outline if we need to */
       if ( hinter->transformed )
       {
         FT_UInt     n     = slot->outline.n_points;
         FT_Vector*  point = slot->outline.points;
-        
 
+
         for ( ; n > 0; point++, n-- )
         {
           point->x += hinter->trans_delta.x;
@@ -1065,7 +1065,7 @@
           point->y += hinter->trans_delta.y;
         }
       }
-      
+
       /* copy the outline points in the loader's current                */
       /* extra points, which is used to keep original glyph coordinates */
       error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
@@ -1365,7 +1365,11 @@
 
     ah_loader_rewind( hinter->loader );
 
+#if 1
+    load_flags = FT_LOAD_NO_SCALE;
+#else
     load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_RECURSE;
+#endif
 
     error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );
 
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -55,7 +55,8 @@
 
   FT_EXPORT_DEF( FT_Fixed )  FT_RoundFix( FT_Fixed  a )
   {
-    return( ( a + 0x8000L ) & -0x10000L );
+    return ( a >= 0 ) ?   ( a + 0x8000L ) & -0x10000L
+                      : -((-a + 0x8000L ) & -0x10000L );
   }
 
 
@@ -63,7 +64,8 @@
 
   FT_EXPORT_DEF( FT_Fixed )  FT_CeilFix( FT_Fixed  a )
   {
-    return( ( a + 0x10000L - 1 ) & -0x10000L );
+    return ( a >= 0 ) ?   ( a + 0xFFFFL ) & -0x10000L
+                      : -((-a + 0xFFFFL ) & -0x10000L );
   }
 
 
@@ -71,7 +73,8 @@
 
   FT_EXPORT_DEF( FT_Fixed )  FT_FloorFix( FT_Fixed  a )
   {
-    return( a & -0x10000L );
+    return ( a >= 0 ) ?   a & -0x10000L
+                      : -((-a) & -0x10000L );
   }
 
 
@@ -176,16 +179,16 @@
     FT_Int32   s;
     FT_UInt32  q;
 
+    s = 1;
+    if ( a < 0 ) { a = -a; s = -1; }
+    if ( b < 0 ) { b = -b; s = -s; }
 
-    s  = a; a = ABS(a);
-    s ^= b; b = ABS(b);
-
     if ( b == 0 )
       /* check for division by 0 */
       q = 0x7FFFFFFFL;
     else
       /* compute result directly */
-      q = ( ((FT_Int64)a + (b >> 1)) << 16 ) / b;
+      q = ( ((FT_Int64)a << 16) + (b >> 1)) / b;
 
     return (FT_Long)( s < 0 ? -q : q );
   }