shithub: freetype+ttf2subf

Download patch

ref: b92479b8c246e5ed1757d6dff2b5687085e0e451
parent: 75133bff1d216f7f45303a375a4f80e296d11902
author: David Turner <[email protected]>
date: Mon Oct 29 05:45:57 EST 2001

experimental changes to debug the auto-hinter. These are not
worthy of a Changelog entry yet..

git/fs: mount .git/fs: mount/attach disallowed
--- a/include/freetype/cache/ftcmanag.h
+++ b/include/freetype/cache/ftcmanag.h
@@ -92,7 +92,7 @@
 
  /* handle to cache class */
   typedef const struct FTC_Cache_ClassRec_*  FTC_Cache_Class;
-  
+
  /* handle to cache node */
   typedef struct FTC_NodeRec_*   FTC_Node;
 
@@ -109,21 +109,17 @@
   /* <Fields>                                                              */
   /*    library      :: A handle to a FreeType library instance.           */
   /*                                                                       */
-  /*    faces_lru    :: The lru list of FT_Face objects in the cache.      */
+  /*    faces_list   :: The lru list of FT_Face objects in the cache.      */
   /*                                                                       */
-  /*    sizes_lru    :: The lru list of FT_Size objects in the cache.      */
+  /*    sizes_list   :: The lru list of FT_Size objects in the cache.      */
   /*                                                                       */
-  /*    max_bytes    :: The maximum number of bytes to be allocated in the */
-  /*                    cache.  This is only related to the byte size of   */
-  /*                    the nodes cached by the manager.                   */
+  /*    max_weight   :: The maximum cache pool weight..                    */
   /*                                                                       */
-  /*    num_bytes    :: The current number of bytes allocated in the       */
-  /*                    cache.  Only related to the byte size of cached    */
-  /*                    nodes.                                             */
+  /*    cur_weight   :: The current cache pool weight.                     */
   /*                                                                       */
   /*    num_nodes    :: The current number of nodes in the manager.        */
   /*                                                                       */
-  /*    global_lru   :: The global lru list of all cache nodes.            */
+  /*    nodes_list   :: The global lru list of all cache nodes.            */
   /*                                                                       */
   /*    caches       :: A table of installed/registered cache objects.     */
   /*                                                                       */
@@ -206,7 +202,7 @@
     FTC_Node   mru_prev;     /* circular mru list pointer           */
     FTC_Node   link;         /* used for hashing..                  */
     FT_UInt32  hash;         /* used for hashing too..              */
-    FT_UShort  cache_index;  /* index of cache this node belongs to */
+    FT_UShort  cache_index;  /* index of cache the node belongs to  */
     FT_Short   ref_count;    /* reference count for this node..     */
   
   } FTC_NodeRec;
--- a/src/autohint/ahglyph.c
+++ b/src/autohint/ahglyph.c
@@ -367,9 +367,9 @@
       vec->x = point->x;
       vec->y = point->y;
 
-      if ( point->flags & ah_flah_conic )
+      if ( point->flags & ah_flag_conic )
         tag[0] = FT_Curve_Tag_Conic;
-      else if ( point->flags & ah_flah_cubic )
+      else if ( point->flags & ah_flag_cubic )
         tag[0] = FT_Curve_Tag_Cubic;
       else
         tag[0] = FT_Curve_Tag_On;
@@ -504,9 +504,9 @@
           switch ( FT_CURVE_TAG( *tag ) )
           {
           case FT_Curve_Tag_Conic:
-            point->flags = ah_flah_conic; break;
+            point->flags = ah_flag_conic; break;
           case FT_Curve_Tag_Cubic:
-            point->flags = ah_flah_cubic; break;
+            point->flags = ah_flag_cubic; break;
           default:
             ;
           }
@@ -570,48 +570,51 @@
         {
           AH_Point*  prev;
           AH_Point*  next;
-          FT_Vector  vec;
+          FT_Vector  ivec, ovec;
 
 
-          prev  = point->prev;
-          vec.x = point->fx - prev->fx;
-          vec.y = point->fy - prev->fy;
+          prev   = point->prev;
+          ivec.x = point->fx - prev->fx;
+          ivec.y = point->fy - prev->fy;
 
-          point->in_dir = ah_compute_direction( vec.x, vec.y );
+          point->in_dir = ah_compute_direction( ivec.x, ivec.y );
 
-#ifndef AH_OPTION_NO_WEAK_INTERPOLATION
-          point->in_angle = ah_angle( &vec );
-#endif
+          next   = point->next;
+          ovec.x = next->fx - point->fx;
+          ovec.y = next->fy - point->fy;
 
-          next  = point->next;
-          vec.x = next->fx - point->fx;
-          vec.y = next->fy - point->fy;
+          point->out_dir = ah_compute_direction( ovec.x, ovec.y );
 
-          point->out_dir = ah_compute_direction( vec.x, vec.y );
-
 #ifndef AH_OPTION_NO_WEAK_INTERPOLATION
-          point->out_angle = ah_angle( &vec );
-
+          if ( point->flags & (ah_flag_conic | ah_flag_cubic) )
           {
-            AH_Angle  delta = point->in_angle - point->out_angle;
+          Is_Weak_Point:
+            point->flags |= ah_flag_weak_interpolation;
+          }
+          else if ( point->out_dir == point->in_dir )
+          {
+            AH_Angle  angle_in, angle_out, delta;
 
 
+            if ( point->out_dir != ah_dir_none )
+              goto Is_Weak_Point;
+            
+            angle_in  = ah_angle( &ivec );
+            angle_out = ah_angle( &ovec );
+            delta     = angle_in - angle_out;
+            
+            if ( delta > AH_PI )
+              delta = AH_2PI - delta;
+
             if ( delta < 0 )
               delta = -delta;
+
             if ( delta < 2 )
-              point->flags |= ah_flah_weak_interpolation;
+              goto Is_Weak_Point;
           }
-
-#if 0
-          if ( point->flags & ( ah_flah_conic | ah_flah_cubic ) )
-            point->flags |= ah_flah_weak_interpolation;
+          else if ( point->in_dir == -point->out_dir )
+            goto Is_Weak_Point;
 #endif
-
-#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */
-
-#ifdef AH_OPTION_NO_STRONG_INTERPOLATION
-          point->flags |= ah_flah_weak_interpolation;
-#endif
         }
       }
     }
@@ -779,7 +782,7 @@
               /* a segment is round if either its first or last point */
               /* is a control point                                   */
               if ( ( segment->first->flags | point->flags ) &
-                     ah_flah_control                        )
+                     ah_flag_control                        )
                 segment->flags |= ah_edge_round;
 
               /* compute segment size */
@@ -997,7 +1000,7 @@
 
               /* before comparing the scores, take care that the segments */
               /* are really facing each other (often not for italics..)   */
-              if ( 4 * len >= size1 && 4 * len >= size2 )
+              if ( 16 * len >= size1 && 16 * len >= size2 )
                 if ( score < best_score )
                 {
                   best_score   = score;
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -209,10 +209,10 @@
       int       has_serifs = 0;
 
 
-      if ( hinter->disable_vert_edges && !dimension )
+      if ( ah_debug_disable_vert && !dimension )
         goto Next_Dimension;
 
-      if ( hinter->disable_horz_edges && dimension )
+      if ( ah_debug_disable_horz && dimension )
         goto Next_Dimension;
 
       /* we begin by aligning all stems relative to the blue zone */
@@ -377,9 +377,10 @@
                         FT_Bool     no_horz_edges,
                         FT_Bool     no_vert_edges )
   {
-    hinter->disable_horz_edges = no_horz_edges;
-    hinter->disable_vert_edges = no_vert_edges;
-
+#if 0  
+    ah_debug_disable_horz = no_horz_edges;
+    ah_debug_disable_vert = no_vert_edges;
+#endif
     /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help      */
     /* reduce the problem of the disappearing eye in the `e' of Times... */
     /* also, creates some artifacts near the blue zones?                 */
@@ -450,12 +451,12 @@
             if ( dimension )
             {
               point->y      = edge->pos;
-              point->flags |= ah_flah_touch_y;
+              point->flags |= ah_flag_touch_y;
             }
             else
             {
               point->x      = edge->pos;
-              point->flags |= ah_flah_touch_x;
+              point->flags |= ah_flag_touch_x;
             }
 
             if ( point == seg->last )
@@ -493,7 +494,7 @@
 
     edges       = outline->horz_edges;
     edge_limit  = edges + outline->num_hedges;
-    touch_flag  = ah_flah_touch_y;
+    touch_flag  = ah_flag_touch_y;
 
     for ( dimension = 1; dimension >= 0; dimension-- )
     {
@@ -514,7 +515,7 @@
 #ifndef AH_OPTION_NO_WEAK_INTERPOLATION
           /* if this point is candidate to weak interpolation, we will  */
           /* interpolate it after all strong points have been processed */
-          if ( point->flags & ah_flah_weak_interpolation )
+          if ( point->flags & ah_flag_weak_interpolation )
             continue;
 #endif
 
@@ -598,7 +599,7 @@
 
       edges      = outline->vert_edges;
       edge_limit = edges + outline->num_vedges;
-      touch_flag = ah_flah_touch_x;
+      touch_flag = ah_flag_touch_x;
     }
   }
 
@@ -707,7 +708,7 @@
 
     /* PASS 1: Move segment points to edge positions */
 
-    touch_flag = ah_flah_touch_y;
+    touch_flag = ah_flag_touch_y;
 
     contour_limit = outline->contours + outline->num_contours;
 
@@ -781,7 +782,7 @@
         for ( point = points; point < point_limit; point++ )
           point->y = point->u;
 
-        touch_flag = ah_flah_touch_x;
+        touch_flag = ah_flag_touch_x;
         ah_setup_uv( outline, ah_uv_ox );
       }
       else
--- a/src/autohint/ahmodule.c
+++ b/src/autohint/ahmodule.c
@@ -26,6 +26,8 @@
 
 #ifdef  DEBUG_HINTER
    extern AH_Hinter*  ah_debug_hinter = NULL;
+   extern FT_Bool     ah_debug_disable_horz = 0;
+   extern FT_Bool     ah_debug_disable_vert = 0;
 #endif
 
   typedef struct  FT_AutoHinterRec_
--- a/src/autohint/ahtypes.h
+++ b/src/autohint/ahtypes.h
@@ -83,7 +83,7 @@
   /* detected and later hinted through strong interpolation to correct     */
   /* some unpleasant artefacts.                                            */
   /*                                                                       */
-#undef AH_OPTION_NO_STRONG_INTERPOLATION
+#define AH_OPTION_NO_STRONG_INTERPOLATION
 
 
   /*************************************************************************/
@@ -126,27 +126,27 @@
 
 
   /* hint flags */
-#define ah_flah_none       0
+#define ah_flag_none       0
 
   /* bezier control points flags */
-#define ah_flah_conic                 1
-#define ah_flah_cubic                 2
-#define ah_flah_control               ( ah_flah_conic | ah_flah_cubic )
+#define ah_flag_conic                 1
+#define ah_flag_cubic                 2
+#define ah_flag_control               ( ah_flag_conic | ah_flag_cubic )
 
   /* extrema flags */
-#define ah_flah_extrema_x             4
-#define ah_flah_extrema_y             8
+#define ah_flag_extrema_x             4
+#define ah_flag_extrema_y             8
 
   /* roundness */
-#define ah_flah_round_x              16
-#define ah_flah_round_y              32
+#define ah_flag_round_x              16
+#define ah_flag_round_y              32
 
   /* touched */
-#define ah_flah_touch_x              64
-#define ah_flah_touch_y             128
+#define ah_flag_touch_x              64
+#define ah_flag_touch_y             128
 
   /* weak interpolation */
-#define ah_flah_weak_interpolation  256
+#define ah_flag_weak_interpolation  256
 
   typedef FT_Int AH_Flags;
 
@@ -485,13 +485,16 @@
     FT_Vector         trans_delta;
     FT_Matrix         trans_matrix;
 
-    FT_Bool           disable_horz_edges;
-    FT_Bool           disable_vert_edges;
   } AH_Hinter;
 
 
 #ifdef    DEBUG_HINTER
   extern AH_Hinter*   ah_debug_hinter;
+  extern FT_Bool      ah_debug_disable_horz;
+  extern FT_Bool      ah_debug_disable_vert;
+#else
+# define ah_debug_disable_horz   0
+# define ah_debug_disable_vert   0
 #endif  /* DEBUG_HINTER */
 
 FT_END_HEADER
--- a/src/cache/ftcmanag.c
+++ b/src/cache/ftcmanag.c
@@ -304,9 +304,12 @@
     manager->library      = library;
     manager->max_weight   = max_bytes;
     manager->cur_weight   = 0;
+
     manager->request_face = requester;
     manager->request_data = req_data;
 
+
+
     *amanager = manager;
 
   Exit:
@@ -348,7 +351,7 @@
         manager->caches[index] = 0;
       }
     }
-
+    
     /* discard faces and sizes */
     FT_LruList_Destroy( manager->faces_list );
     manager->faces_list = 0;
--- a/tests/gview.c
+++ b/tests/gview.c
@@ -63,14 +63,17 @@
  /************************************************************************/
  /************************************************************************/
 
-static  int   option_show_axis   = 1;
-static  int   option_show_dots   = 1;
-static  int   option_show_stroke = 0;
-static  int   option_show_glyph  = 1;
-static  int   option_show_grid   = 1;
-static  int   option_show_em     = 0;
-static  int   option_show_smooth = 1;
-static  int   option_show_blues  = 0;
+static  int   option_show_axis     = 1;
+static  int   option_show_dots     = 1;
+static  int   option_show_stroke   = 0;
+static  int   option_show_glyph    = 1;
+static  int   option_show_grid     = 1;
+static  int   option_show_em       = 0;
+static  int   option_show_smooth   = 1;
+static  int   option_show_blues    = 0;
+static  int   option_show_edges    = 0;
+static  int   option_show_segments = 1;
+static  int   option_show_links    = 1;
 
 static  int   option_show_ps_hints   = 1;
 static  int   option_show_horz_hints = 1;
@@ -106,6 +109,11 @@
 #define  STEM_HINT_COLOR   0xE02020FF
 #define  STEM_JOIN_COLOR   0xE020FF20
 
+#define  EDGE_COLOR        0xF0704070
+#define  SEGMENT_COLOR     0xF0206040
+#define  LINK_COLOR        0xF0FFFF00
+#define  SERIF_LINK_COLOR  0xF0FF808F  
+
 /* print message and abort program */
 static void
 Panic( const char*  message )
@@ -607,18 +615,251 @@
  /************************************************************************/
  /************************************************************************/
 
+static NV_Path
+ah_link_path( NV_Vector*   p1,
+              NV_Vector*   p4,
+              NV_Bool      vertical )
+{
+  NV_PathWriter  writer;
+  NV_Vector      p2, p3;
+  NV_Path        path, stroke;
+
+  if ( vertical )
+  {
+    p2.x = p4->x;
+    p2.y = p1->y;
+    
+    p3.x = p1->x;
+    p3.y = p4->y;
+  }
+  else
+  {
+    p2.x = p1->x;
+    p2.y = p4->y;
+    
+    p3.x = p4->x;
+    p3.y = p1->y;
+  }  
+  
+  nv_path_writer_new( renderer, &writer );
+  nv_path_writer_moveto( writer, p1 );
+  nv_path_writer_cubicto( writer, &p2, &p3, p4 );
+  nv_path_writer_end( writer );
+  
+  path = nv_path_writer_get_path( writer );
+  nv_path_writer_destroy( writer );
+  
+  nv_path_stroke( path, 1., nv_path_linecap_butt, nv_path_linejoin_round, 1.,  &stroke );
+  
+  nv_path_destroy( path );
+  
+  return stroke;
+}              
+
+
 static void
-ah_draw_smooth_points( AH_Hinter  hinter )
+ah_draw_smooth_points( void )
 {
-  if ( ah_debug_hinter )
+  if ( ah_debug_hinter && option_show_smooth )
   {
+    AH_Outline*  glyph = ah_debug_hinter->glyph;
+    FT_UInt      count = glyph->num_points;
+    AH_Point*    point = glyph->points;
     
+    nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
+    
+    for ( ; count > 0; count--, point++ )
+    {
+      if ( !( point->flags & ah_flag_weak_interpolation ) )
+      {
+        NV_Transform  transform, *trans = &transform;
+        NV_Vector     vec;
+        
+        vec.x = point->x - ah_debug_hinter->pp1.x;
+        vec.y = point->y;
+        nv_vector_transform( &vec, &size_transform );
+        
+        nv_transform_set_translate( &transform, vec.x, vec.y );
+        nv_painter_fill_path( painter, trans, 0, symbol_circle );
+      }
+    }
   }
 }
 
+
 static void
-ah_draw_edges( AH_Hinter  hinter )
+ah_draw_edges( void )
 {
+  if ( ah_debug_hinter )
+  {
+    AH_Outline*  glyph = ah_debug_hinter->glyph;
+    FT_UInt      count;
+    AH_Edge*     edge;
+    FT_Pos       pp1 = ah_debug_hinter->pp1.x;
+    
+    nv_painter_set_color( painter, EDGE_COLOR, 256 );
+
+    if ( option_show_edges )
+    {
+      /* draw verticla edges */
+      if ( option_show_vert_hints )
+      {    
+        count = glyph->num_vedges;
+        edge  = glyph->vert_edges;
+        for ( ; count > 0; count--, edge++ )
+        {
+          NV_Vector     vec;
+          NV_Pos        x;
+          
+          vec.x = edge->pos - pp1;
+          vec.y = 0;
+          
+          nv_vector_transform( &vec, &size_transform );
+          x = (FT_Pos)( vec.x + 0.5 );
+          
+          nv_pixmap_fill_rect( target, x, 0, 1, target->height, EDGE_COLOR );
+        }
+      }
+  
+      /* draw horizontal edges */
+      if ( option_show_horz_hints )
+      {
+        count = glyph->num_hedges;
+        edge  = glyph->horz_edges;
+        for ( ; count > 0; count--, edge++ )
+        {
+          NV_Vector     vec;
+          NV_Pos        x;
+          
+          vec.x = 0;
+          vec.y = edge->pos;
+          
+          nv_vector_transform( &vec, &size_transform );
+          x = (FT_Pos)( vec.y + 0.5 );
+          
+          nv_pixmap_fill_rect( target, 0, x, target->width, 1, EDGE_COLOR );
+        }
+      }
+    }
+    
+    if ( option_show_segments )
+    {
+      /* draw vertical segments */
+      if ( option_show_vert_hints )
+      {
+        AH_Segment*  seg   = glyph->vert_segments;
+        FT_UInt      count = glyph->num_vsegments;
+        
+        for ( ; count > 0; count--, seg++ )
+        {
+          AH_Point  *first, *last;
+          NV_Vector  v1, v2;
+          NV_Pos     y1, y2, x;
+          
+          first = seg->first;
+          last  = seg->last;
+          
+          v1.x = v2.x = first->x - pp1;
+          
+          if ( first->y <= last->y )
+          {
+            v1.y = first->y;
+            v2.y = last->y;
+          }
+          else
+          {
+            v1.y = last->y;
+            v2.y = first->y;
+          }
+          
+          nv_vector_transform( &v1, &size_transform );
+          nv_vector_transform( &v2, &size_transform );
+          
+          y1 = (NV_Pos)( v1.y + 0.5 );
+          y2 = (NV_Pos)( v2.y + 0.5 );
+          x  = (NV_Pos)( v1.x + 0.5 );
+          
+          nv_pixmap_fill_rect( target, x-1, y2, 3, ABS(y1-y2)+1, SEGMENT_COLOR );
+        }
+      }
+      
+      /* draw horizontal segments */
+      if ( option_show_horz_hints )
+      {
+        AH_Segment*  seg   = glyph->horz_segments;
+        FT_UInt      count = glyph->num_hsegments;
+        
+        for ( ; count > 0; count--, seg++ )
+        {
+          AH_Point  *first, *last;
+          NV_Vector  v1, v2;
+          NV_Pos     y1, y2, x;
+          
+          first = seg->first;
+          last  = seg->last;
+          
+          v1.y = v2.y = first->y;
+          
+          if ( first->x <= last->x )
+          {
+            v1.x = first->x - pp1;
+            v2.x = last->x - pp1;
+          }
+          else
+          {
+            v1.x = last->x - pp1;
+            v2.x = first->x - pp1;
+          }
+          
+          nv_vector_transform( &v1, &size_transform );
+          nv_vector_transform( &v2, &size_transform );
+          
+          y1 = (NV_Pos)( v1.x + 0.5 );
+          y2 = (NV_Pos)( v2.x + 0.5 );
+          x  = (NV_Pos)( v1.y + 0.5 );
+          
+          nv_pixmap_fill_rect( target, y1, x-1, ABS(y1-y2)+1, 3, SEGMENT_COLOR );
+        }
+      }
+
+
+      if ( option_show_vert_hints && option_show_links )
+      {
+        AH_Segment*  seg   = glyph->vert_segments;
+        FT_UInt      count = glyph->num_vsegments;
+        
+        for ( ; count > 0; count--, seg++ )
+        {
+          AH_Segment*  seg2 = NULL;
+          NV_Path      link;
+          NV_Vector    v1, v2;
+          
+          if ( seg->link )
+          {
+            if ( seg->link > seg )
+              seg2 = seg->link;
+          }
+          else if ( seg->serif )
+            seg2 = seg->serif;
+          
+          if ( seg2 )
+          {
+            v1.x = seg->first->x  - pp1;
+            v2.x = seg2->first->x - pp1;
+            v1.y = (seg->first->y + seg->last->y)/2;
+            v2.y = (seg2->first->y + seg2->last->y)/2;
+            
+            link = ah_link_path( &v1, &v2, 1 );
+            
+            nv_painter_set_color( painter, seg->serif ? SERIF_LINK_COLOR : LINK_COLOR, 256 );
+            nv_painter_fill_path( painter, &size_transform, 0, link );
+  
+            nv_path_destroy( link );
+          }
+        }
+      }
+    }
+  }
 }
 
  /************************************************************************/
@@ -717,6 +958,9 @@
     }
   }
 
+  ah_draw_smooth_points();
+  ah_draw_edges();
+  
   nv_path_destroy( path );
   
   /* autre infos */
@@ -908,7 +1152,7 @@
 
 int  main( int  argc, char**  argv )
 {
-  char*  filename = "/fonts/lcdxsr.pfa";
+  char*  filename = "/winnt/fonts/arial.ttf";
   
   parse_options( &argc, &argv );
   
@@ -958,7 +1202,12 @@
       clear_background();
       draw_grid();
 
-      ps_debug_hints = 0;
+      ps_debug_hints  = 0;
+      ah_debug_hinter = 0;
+
+      ah_debug_disable_vert = ps_debug_no_vert_hints;
+      ah_debug_disable_horz = ps_debug_no_horz_hints;
+
       draw_ps_blue_zones();
       draw_glyph( glyph_index );
       ps2_draw_control_points();