shithub: freetype+ttf2subf

Download patch

ref: f2c56515f5e0279c93e9fc5c8c6167daf13eaffd
parent: adf07a930cb0ce44a57018a2c5edbc9ac8916d88
author: David Turner <[email protected]>
date: Mon Nov 19 20:29:34 EST 2001

* src/pshinter/{pshalgo2.c, pshalgo1.c}: fixed stupid bug in sorting
        routine that created nasty alignment artefacts.

        * src/pshinter/pshrec.c, tests/gview.c: debugging updates..

        * src/smooth/ftgrays.c: de-activated experimental gamme support,
        apparently, "optimal" gamma tables depend on the monitor type,
        resolution and general karma, so it's better to compute them outside
        of the rasterizer itself..

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,26 @@
+2001-11-20  David Turner       <[email protected]>
+
+        * src/pshinter/{pshalgo2.c, pshalgo1.c}: fixed stupid bug in sorting
+        routine that created nasty alignment artefacts.
+
+        * src/pshinter/pshrec.c, tests/gview.c: debugging updates..
+
+        * src/smooth/ftgrays.c: de-activated experimental gamme support,
+        apparently, "optimal" gamma tables depend on the monitor type,
+        resolution and general karma, so it's better to compute them outside
+        of the rasterizer itself..
+
+
 2001-10-29  David Turner       <[email protected]>
 
 	* src/smooth/ftgrays.c: adding experimental "gamma" support. This
 	produces smoother glyphs at small sizes for very little cost
-	
+
 	* src/autohint/ahglyph.c, src/autohint/ahhint.c: various fixes to
 	the auto-hinter. They merely improve the output of sans-serif fonts.
 	Note that there are still problems with serifed fonts and composites
 	(accented characters)
-	
+
 	* tests/gview.c: updated the debugging glyph viewer to show the
 	hints generated by the "autohint" module
 
@@ -22,15 +35,15 @@
         * include/freetype/ftcache.h, include/freetype/cache/*.h,
         src/cache/*.c: Major re-design of the cache sub-system to provide
         better performance as well as an "Acquire"/"Release" API..
-        
+
         seems to work well here.. but probably needs a bit more testing..
-        
 
+
 2001-10-26  Leonard Rosenthol  <[email protected]>
 
 	* updated Mac OS README (builds/mac/) to reflect my taking over
 	the project and that is now being actively maintained.
-	
+
 	* Applied patches from Paul Miller (<[email protected]>)
 	to /src/base/ftmac.c to support loading a face other than the
 	first from a FOND resource.
@@ -61,8 +74,8 @@
 	improvements to the memory debugger to report more information in
 	case of errors. Also, some allocations that occured through
 	REALLOC couldn't be previously catched correctly..
-	
 
+
 	* src/autohint/ahglyph.c, src/raster/ftraster.c,
 	src/smooth/ftgrays.c: replaced liberal uses of "memset" by the
 	MEM_Set macro instead..
@@ -87,10 +100,10 @@
 	the FT_DEBUG_MEMORY macro in "ftoption.h" to enable it. It will record
 	every memory block allocated and report simple errors like memory
 	leaks and double deletes.
-	
+
 	* include/freetype/config/ftoption.h: added the FT_DEBUG_MEMORY macro
 	definition
-	
+
 	* src/base/ftsystem.c (FT_New_Memory, FT_Done_Memory): modified the
 	base component to use the debugging memory manager when the macro
 	FT_DEBUG_MEMORY is defined..
@@ -115,7 +128,7 @@
 
 
 2001-10-20  Tom Kacvinsky  <[email protected]>
-	
+
 	* src/type1/t1load.c (parse_encoding): Add a test to make sure
 	that custom encodings (i.e., neither StandardEncoding nor
 	ExpertEncoding) are not loaded twice when the Type 1 font is
@@ -162,7 +175,7 @@
         some strange bugs in the Postscript hinter
 
         * src/cid/cidgload.c: adding support to new postscript hinter
-        
+
         * include/freetype/internal/psglobal.h,
           include/freetype/internal/pshints.h,
           include/freetype/config/ftmodule.h,
@@ -276,7 +289,7 @@
 	Provide a public API to manage multiple size objects for a given
 	FT_Face in the new header file `ftsizes.h'.
 
-	* include/freetype/ftsizes.h: New header file, 
+	* include/freetype/ftsizes.h: New header file,
 	* include/freetype/internal/ftobjs.h: Use it.
 	Remove declarations of FT_New_Size and FT_Done_Size (moved to
 	ftsizes.h).
@@ -520,7 +533,7 @@
 2001-06-22  David Turner <[email protected]>
 
 	* docs/PATENTS: Added patents disclaimer.  This one was missing!
-    
+
 	* docs/CHANGES, docs/todo: Updated for the upcoming 2.0.4 release.
 
 2001-06-20  Werner Lemberg  <[email protected]>
--- a/src/pshinter/pshalgo1.c
+++ b/src/pshinter/pshalgo1.c
@@ -15,7 +15,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
- 
+
  /* return true iff two stem hints overlap */
   static FT_Int
   psh1_hint_overlap( PSH1_Hint  hint1,
@@ -24,8 +24,8 @@
     return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&
              hint2->org_pos + hint2->org_len >= hint1->org_pos );
   }
- 
- 
+
+
  /* destroy hints table */
   static void
   psh1_hint_table_done( PSH1_Hint_Table  table,
@@ -34,7 +34,7 @@
     FREE( table->zones );
     table->num_zones = 0;
     table->zone      = 0;
-    
+
     FREE( table->sort );
     FREE( table->hints );
     table->num_hints   = 0;
@@ -49,7 +49,7 @@
   {
     FT_UInt   count = table->max_hints;
     PSH1_Hint  hint  = table->hints;
-    
+
     for ( ; count > 0; count--, hint++ )
     {
       psh1_hint_deactivate(hint);
@@ -70,13 +70,13 @@
       FT_ERROR(( "%s.activate: invalid hint index %d\n", index ));
       return;
     }
-        
+
     /* ignore active hints */
     if ( psh1_hint_is_active(hint) )
       return;
-    
+
     psh1_hint_activate(hint);
-    
+
     /* now scan the current active hint set in order to determine */
     /* if we're overlapping with another segment..                */
     {
@@ -84,11 +84,11 @@
       FT_UInt     count  = table->num_hints;
       PSH1_Hint   hint2;
 
-      hint->parent = 0;      
+      hint->parent = 0;
       for ( ; count > 0; count--, sorted++ )
       {
         hint2 = sorted[0];
-        
+
         if ( psh1_hint_overlap( hint, hint2 ) )
         {
           hint->parent = hint2;
@@ -96,7 +96,7 @@
         }
       }
     }
-    
+
     if ( table->num_hints < table->max_hints )
       table->sort_global[ table->num_hints++ ] = hint;
     else
@@ -115,14 +115,14 @@
     FT_Byte*  cursor = hint_mask->bytes;
     FT_UInt   index, limit;
 
-    limit = hint_mask->num_bits; 
-    
+    limit = hint_mask->num_bits;
+
     if ( limit != table->max_hints )
     {
       FT_ERROR(( "%s.activate_mask: invalid bit count (%d instead of %d)\n",
                  "ps.fitter", hint_mask->num_bits, table->max_hints ));
     }
-        
+
     for ( index = 0; index < limit; index++ )
     {
       if ( mask == 0 )
@@ -130,10 +130,10 @@
         val  = *cursor++;
         mask = 0x80;
       }
-      
+
       if ( val & mask )
         psh1_hint_table_record( table, index );
-        
+
       mask >>= 1;
     }
   }
@@ -151,24 +151,24 @@
     FT_Error  error;
 
     FT_UNUSED(counter_masks);
-    
+
     /* allocate our tables */
     if ( ALLOC_ARRAY( table->sort,  2*count,   PSH1_Hint    ) ||
          ALLOC_ARRAY( table->hints,   count,   PSH1_HintRec ) ||
          ALLOC_ARRAY( table->zones, 2*count+1, PSH1_ZoneRec ) )
       goto Exit;
-    
+
     table->max_hints   = count;
     table->sort_global = table->sort + count;
     table->num_hints   = 0;
     table->num_zones   = 0;
     table->zone        = 0;
-    
+
     /* now, initialise the "hints" array */
     {
       PSH1_Hint  write = table->hints;
       PS_Hint   read  = hints->hints;
-      
+
       for ( ; count > 0; count--, write++, read++ )
       {
         write->org_pos = read->pos;
@@ -185,22 +185,22 @@
       PS_Mask  mask  = hint_masks->masks;
 
       table->hint_masks = hint_masks;
-      
+
       for ( ; count > 0; count--, mask++ )
         psh1_hint_table_record_mask( table, mask );
     }
-    
+
     /* now, do a linear parse in case some hints were left alone */
     if ( table->num_hints != table->max_hints )
     {
       FT_UInt   index, count;
-      
+
       FT_ERROR(( "%s.init: missing/incorrect hint masks !!\n" ));
       count = table->max_hints;
       for ( index = 0; index < count; index++ )
         psh1_hint_table_record( table, index );
-    }    
-    
+    }
+
   Exit:
     return error;
   }
@@ -215,11 +215,11 @@
     FT_Byte*  cursor = hint_mask->bytes;
     FT_UInt   index, limit, count;
 
-    limit = hint_mask->num_bits; 
+    limit = hint_mask->num_bits;
     count = 0;
 
     psh1_hint_table_deactivate( table );
-    
+
     for ( index = 0; index < limit; index++ )
     {
       if ( mask == 0 )
@@ -227,17 +227,17 @@
         val  = *cursor++;
         mask = 0x80;
       }
-      
+
       if ( val & mask )
       {
         PSH1_Hint  hint = &table->hints[index];
-        
+
         if ( !psh1_hint_is_active(hint) )
         {
           PSH1_Hint*  sort   = table->sort;
           FT_UInt    count2;
           PSH1_Hint   hint2;
-          
+
           for ( count2 = count; count2 > 0; count2--, sort++ )
           {
             hint2 = sort[0];
@@ -248,7 +248,7 @@
               break;
             }
           }
-          
+
           if ( count2 == 0 )
           {
             psh1_hint_activate( hint );
@@ -258,15 +258,15 @@
             {
               FT_ERROR(( "%s.activate_mask: too many active hints\n",
                          "psf.hint" ));
-            } 
+            }
           }
         }
       }
-        
+
       mask >>= 1;
     }
     table->num_hints = count;
-    
+
     /* now, sort the hints, they're guaranteed to not overlap */
     /* so we can compare their "org_pos" field directly..     */
     {
@@ -284,9 +284,9 @@
           hint2 = sort[i2];
           if ( hint2->org_pos < hint1->org_pos )
             break;
-            
-          sort[i1] = hint2;
-          sort[i2] = hint1;
+
+          sort[i2+1] = hint2;
+          sort[i2]   = hint1;
         }
       }
     }
@@ -305,7 +305,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
- 
+
 #ifdef DEBUG_HINTER
   void
   ps_simple_scale( PSH1_Hint_Table  table,
@@ -315,7 +315,7 @@
   {
     PSH1_Hint  hint;
     FT_UInt    count;
-  
+
     for ( count = 0; count < table->num_hints; count++ )
     {
       hint = table->sort[count];
@@ -323,12 +323,12 @@
       {
         hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
         hint->cur_len = FT_MulFix( hint->org_len, scale );
-        
+
         if (ps1_debug_hint_func)
           ps1_debug_hint_func( hint, vertical );
       }
     }
-  }                
+  }
 #endif
 
   FT_LOCAL_DEF  FT_Error
@@ -349,7 +349,7 @@
       ps_simple_scale( table, scale, delta, vertical );
       return 0;
     }
-      
+
     if ( ps_debug_no_horz_hints && !vertical )
     {
       ps_simple_scale( table, scale, delta, vertical );
@@ -359,10 +359,10 @@
 
     /* XXXX: for now, we only scale the hints to test all other aspects */
     /*       of the Postscript Hinter..                                 */
-    {  
+    {
       PSH1_Hint  hint;
       FT_UInt   count;
-    
+
       for ( count = 0; count < table->num_hints; count++ )
       {
         hint = table->sort[count];
@@ -371,10 +371,10 @@
 # if 1
           FT_Pos   pos = FT_MulFix( hint->org_pos, scale ) + delta;
           FT_Pos   len = FT_MulFix( hint->org_len, scale );
-          
+
           FT_Pos   fit_center;
           FT_Pos   fit_len;
-          
+
           PSH_AlignmentRec  align;
 
           /* compute fitted width/height */
@@ -383,9 +383,9 @@
             fit_len = 64;
           else
             fit_len = (fit_len + 32 ) & -64;
-            
+
           hint->cur_len = fit_len;
-            
+
           /* check blue zones for horizontal stems */
           align.align     = 0;
           align.align_bot = align.align_top = 0;
@@ -405,7 +405,7 @@
                 hint->cur_pos = align.align_top - fit_len;
                 break;
               }
-              
+
             case PSH_BLUE_ALIGN_BOT:
               {
                 /* the bottom of the stem is aligned against a blue zone */
@@ -412,7 +412,7 @@
                 hint->cur_pos = align.align_bot;
                 break;
               }
-              
+
             case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
               {
                 /* both edges of the stem are aligned against blue zones */
@@ -420,7 +420,7 @@
                 hint->cur_len = align.align_top - align.align_bot;
               }
               break;
-              
+
             default:
               /* normal processing */
               if ( (fit_len/64) & 1 )
@@ -433,22 +433,22 @@
                 /* even number of pixels */
                 fit_center = (pos + (len >> 1) + 32) & -64;
               }
-              
+
               hint->cur_pos = fit_center - (fit_len >> 1);
           }
 # else
           hint->cur_pos = (FT_MulFix( hint->org_pos, scale ) + delta + 32) & -64;
           hint->cur_len =  FT_MulFix( hint->org_len, scale );
-# endif          
+# endif
 
 #ifdef DEBUG_HINTER
         if (ps1_debug_hint_func)
           ps1_debug_hint_func( hint, vertical );
-#endif        
+#endif
         }
       }
     }
-    
+
     return 0;
   }
 
@@ -462,7 +462,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
- 
+
 #define  PSH1_ZONE_MIN  -3200000
 #define  PSH1_ZONE_MAX  +3200000
 
@@ -497,9 +497,9 @@
     FT_UInt   count;
     PSH1_Zone  zone;
     PSH1_Hint *sort, hint, hint2;
-    
+
     zone  = table->zones;
-    
+
     /* special case, no hints defined */
     if ( table->num_hints == 0 )
     {
@@ -507,26 +507,26 @@
       zone->delta = delta;
       zone->min   = PSH1_ZONE_MIN;
       zone->max   = PSH1_ZONE_MAX;
-      
+
       table->num_zones = 1;
       table->zone      = zone;
       return;
     }
-    
+
     /* the first zone is before the first hint */
     /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
     sort  = table->sort;
     hint  = sort[0];
-    
+
     zone->scale = scale;
     zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
     zone->min   = PSH1_ZONE_MIN;
     zone->max   = hint->org_pos;
-    
+
     print_zone( zone );
-    
+
     zone++;
-    
+
     for ( count = table->num_hints; count > 0; count-- )
     {
       FT_Fixed  scale2;
@@ -536,7 +536,7 @@
         /* setup a zone for inner-stem interpolation */
         /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0)   */
         /* x' = x*s2 + x0' - x0*s2                   */
-        
+
         scale2      = FT_DivFix( hint->cur_len, hint->org_len );
         zone->scale = scale2;
         zone->min   = hint->org_pos;
@@ -544,16 +544,16 @@
         zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
 
         print_zone( zone );
-    
+
         zone++;
       }
-      
+
       if ( count == 1 )
         break;
-        
+
       sort++;
       hint2 = sort[0];
-      
+
       /* setup zone for inter-stem interpolation */
       /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1)     */
       /* x' = x*s3 + x1' - x1*s3                 */
@@ -565,9 +565,9 @@
       zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 );
 
       print_zone( zone );
-    
+
       zone++;
-      
+
       hint  = hint2;
     }
 
@@ -578,23 +578,23 @@
     zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale );
 
     print_zone( zone );
-    
+
     zone++;
-    
+
     table->num_zones = zone - table->zones;
     table->zone      = table->zones;
   }
 
 
- /* tune a single coordinate with the current interpolation zones */  
+ /* tune a single coordinate with the current interpolation zones */
   static FT_Pos
   psh1_hint_table_tune_coord( PSH1_Hint_Table  table,
                               FT_Int           coord )
   {
     PSH1_Zone   zone;
-    
+
     zone = table->zone;
-      
+
     if ( coord < zone->min )
     {
       do
@@ -601,7 +601,7 @@
       {
         if ( zone == table->zones )
           break;
-          
+
         zone--;
       }
       while ( coord < zone->min );
@@ -613,13 +613,13 @@
       {
         if ( zone == table->zones + table->num_zones - 1 )
           break;
-          
+
         zone++;
       }
       while ( coord > zone->max );
       table->zone = zone;
     }
-        
+
     return FT_MulFix( coord, zone->scale ) + zone->delta;
   }
 
@@ -639,7 +639,7 @@
     PSH_Dimension  dim        = &globals->dimension[vertical];
     FT_Fixed        scale      = dim->scale_mult;
     FT_Fixed        delta      = dim->scale_delta;
-    
+
     if ( hint_masks && hint_masks->num_masks > 0 )
     {
       first = 0;
@@ -648,30 +648,30 @@
       for ( ; count > 0; count--, mask++ )
       {
         last = mask->end_point;
-        
+
         if ( last > first )
         {
           FT_Vector*   vec;
           FT_Int       count2;
-          
+
           psh1_hint_table_activate_mask( table, mask );
           psh1_hint_table_optimize( table, globals, outline, vertical );
           psh1_hint_table_setup_zones( table, scale, delta );
           last = mask->end_point;
-          
+
           vec    = outline->points + first;
           count2 = last - first;
           for ( ; count2 > 0; count2--, vec++ )
           {
             FT_Pos  x, *px;
-            
+
             px  = vertical ? &vec->x : &vec->y;
             x   = *px;
-            
+
             *px = psh1_hint_table_tune_coord( table, (FT_Int)x );
           }
         }
-          
+
         first = last;
       }
     }
@@ -678,10 +678,10 @@
     else    /* no hints in this glyph, simply scale the outline */
     {
       FT_Vector*  vec;
-      
+
       vec   = outline->points;
       count = outline->n_points;
-      
+
       if ( vertical )
       {
         for ( ; count > 0; count--, vec++ )
@@ -694,8 +694,8 @@
       }
     }
   }
-  
-  
+
+
  /************************************************************************/
  /************************************************************************/
  /*****                                                              *****/
@@ -703,7 +703,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
-  
+
   FT_Error
   ps1_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
@@ -712,11 +712,11 @@
     PSH1_Hint_TableRec  hints;
     FT_Error            error = 0;
     FT_Int              dimension;
-    
+
     for ( dimension = 1; dimension >= 0; dimension-- )
     {
       PS_Dimension  dim = &ps_hints->dimension[dimension];
-      
+
       /* initialise hints table */
       memset( &hints, 0, sizeof(hints) );
       error = psh1_hint_table_init( &hints,
@@ -725,15 +725,15 @@
                                     &dim->counters,
                                     ps_hints->memory );
       if (error) goto Exit;
-      
+
       psh1_hint_table_tune_outline( &hints,
                                     outline,
                                     globals,
                                     dimension );
-                                   
+
       psh1_hint_table_done( &hints, ps_hints->memory );
     }
-    
+
   Exit:
-    return error;                                   
+    return error;
   }
--- a/src/pshinter/pshalgo2.c
+++ b/src/pshinter/pshalgo2.c
@@ -4,7 +4,7 @@
 #include "pshalgo2.h"
 
 
-#ifdef DEBUG_HINTER  
+#ifdef DEBUG_HINTER
   extern  PSH2_Hint_Table  ps2_debug_hint_table  = 0;
   extern  PSH2_HintFunc    ps2_debug_hint_func   = 0;
   extern  PSH2_Glyph       ps2_debug_glyph       = 0;
@@ -17,7 +17,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
- 
+
  /* return true iff two stem hints overlap */
   static FT_Int
   psh2_hint_overlap( PSH2_Hint  hint1,
@@ -26,8 +26,8 @@
     return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&
              hint2->org_pos + hint2->org_len >= hint1->org_pos );
   }
- 
- 
+
+
  /* destroy hints table */
   static void
   psh2_hint_table_done( PSH2_Hint_Table  table,
@@ -36,7 +36,7 @@
     FREE( table->zones );
     table->num_zones = 0;
     table->zone      = 0;
-    
+
     FREE( table->sort );
     FREE( table->hints );
     table->num_hints   = 0;
@@ -51,7 +51,7 @@
   {
     FT_UInt   count = table->max_hints;
     PSH2_Hint  hint  = table->hints;
-    
+
     for ( ; count > 0; count--, hint++ )
     {
       psh2_hint_deactivate(hint);
@@ -72,13 +72,13 @@
       FT_ERROR(( "%s.activate: invalid hint index %d\n", index ));
       return;
     }
-        
+
     /* ignore active hints */
     if ( psh2_hint_is_active(hint) )
       return;
-    
+
     psh2_hint_activate(hint);
-    
+
     /* now scan the current active hint set in order to determine */
     /* if we're overlapping with another segment..                */
     {
@@ -86,11 +86,11 @@
       FT_UInt     count  = table->num_hints;
       PSH2_Hint   hint2;
 
-      hint->parent = 0;      
+      hint->parent = 0;
       for ( ; count > 0; count--, sorted++ )
       {
         hint2 = sorted[0];
-        
+
         if ( psh2_hint_overlap( hint, hint2 ) )
         {
           hint->parent = hint2;
@@ -98,7 +98,7 @@
         }
       }
     }
-    
+
     if ( table->num_hints < table->max_hints )
       table->sort_global[ table->num_hints++ ] = hint;
     else
@@ -117,8 +117,8 @@
     FT_Byte*  cursor = hint_mask->bytes;
     FT_UInt   index, limit;
 
-    limit = hint_mask->num_bits; 
-    
+    limit = hint_mask->num_bits;
+
     for ( index = 0; index < limit; index++ )
     {
       if ( mask == 0 )
@@ -126,10 +126,10 @@
         val  = *cursor++;
         mask = 0x80;
       }
-      
+
       if ( val & mask )
         psh2_hint_table_record( table, index );
-        
+
       mask >>= 1;
     }
   }
@@ -147,24 +147,24 @@
     FT_Error  error;
 
     FT_UNUSED(counter_masks);
-    
+
     /* allocate our tables */
     if ( ALLOC_ARRAY( table->sort,  2*count,   PSH2_Hint    ) ||
          ALLOC_ARRAY( table->hints,   count,   PSH2_HintRec ) ||
          ALLOC_ARRAY( table->zones, 2*count+1, PSH2_ZoneRec ) )
       goto Exit;
-    
+
     table->max_hints   = count;
     table->sort_global = table->sort + count;
     table->num_hints   = 0;
     table->num_zones   = 0;
     table->zone        = 0;
-    
+
     /* now, initialise the "hints" array */
     {
       PSH2_Hint  write = table->hints;
       PS_Hint   read  = hints->hints;
-      
+
       for ( ; count > 0; count--, write++, read++ )
       {
         write->org_pos = read->pos;
@@ -181,22 +181,22 @@
       PS_Mask  mask  = hint_masks->masks;
 
       table->hint_masks = hint_masks;
-      
+
       for ( ; count > 0; count--, mask++ )
         psh2_hint_table_record_mask( table, mask );
     }
-    
+
     /* now, do a linear parse in case some hints were left alone */
     if ( table->num_hints != table->max_hints )
     {
       FT_UInt   index, count;
-      
+
       FT_ERROR(( "%s.init: missing/incorrect hint masks !!\n" ));
       count = table->max_hints;
       for ( index = 0; index < count; index++ )
         psh2_hint_table_record( table, index );
-    }    
-    
+    }
+
   Exit:
     return error;
   }
@@ -211,11 +211,11 @@
     FT_Byte*  cursor = hint_mask->bytes;
     FT_UInt   index, limit, count;
 
-    limit = hint_mask->num_bits; 
+    limit = hint_mask->num_bits;
     count = 0;
 
     psh2_hint_table_deactivate( table );
-    
+
     for ( index = 0; index < limit; index++ )
     {
       if ( mask == 0 )
@@ -223,15 +223,15 @@
         val  = *cursor++;
         mask = 0x80;
       }
-      
+
       if ( val & mask )
       {
         PSH2_Hint  hint = &table->hints[index];
-        
+
         if ( !psh2_hint_is_active(hint) )
         {
           FT_UInt     count2;
-          
+
 #if 0
           PSH2_Hint*  sort = table->sort;
           PSH2_Hint   hint2;
@@ -248,7 +248,7 @@
 #else
           count2 = 0;
 #endif
-          
+
           if ( count2 == 0 )
           {
             psh2_hint_activate( hint );
@@ -258,15 +258,15 @@
             {
               FT_ERROR(( "%s.activate_mask: too many active hints\n",
                          "psf.hint" ));
-            } 
+            }
           }
         }
       }
-        
+
       mask >>= 1;
     }
     table->num_hints = count;
-    
+
     /* now, sort the hints, they're guaranteed to not overlap */
     /* so we can compare their "org_pos" field directly..     */
     {
@@ -282,11 +282,12 @@
         for ( i2 = i1-1; i2 >= 0; i2-- )
         {
           hint2 = sort[i2];
+
           if ( hint2->org_pos < hint1->org_pos )
             break;
-            
-          sort[i1] = hint2;
-          sort[i2] = hint1;
+
+          sort[i2+1] = hint2;
+          sort[i2]   = hint1;
         }
       }
     }
@@ -305,7 +306,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
- 
+
 #ifdef DEBUG_HINTER
   static void
   ps2_simple_scale( PSH2_Hint_Table  table,
@@ -315,7 +316,7 @@
   {
     PSH2_Hint  hint;
     FT_UInt    count;
-  
+
     for ( count = 0; count < table->max_hints; count++ )
     {
       hint = table->hints + count;
@@ -322,11 +323,11 @@
 
       hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta;
       hint->cur_len = FT_MulFix( hint->org_len, scale );
-        
+
       if (ps2_debug_hint_func)
         ps2_debug_hint_func( hint, vertical );
     }
-  }                
+  }
 #endif
 
 
@@ -340,13 +341,13 @@
     FT_Fixed       delta = dim->scale_delta;
 
     if ( !psh2_hint_is_fitted(hint) )
-    {      
+    {
       FT_Pos   pos = FT_MulFix( hint->org_pos, scale ) + delta;
       FT_Pos   len = FT_MulFix( hint->org_len, scale );
-      
+
       FT_Pos   fit_center;
       FT_Pos   fit_len;
-      
+
       PSH_AlignmentRec  align;
 
       /* compute fitted width/height */
@@ -359,13 +360,13 @@
         else
           fit_len = (fit_len + 32 ) & -64;
       }
-        
+
       hint->cur_len = fit_len;
-        
+
       /* check blue zones for horizontal stems */
       align.align = 0;
       align.align_bot = align.align_top = 0;
-      
+
       if (!vertical)
       {
         psh_blues_snap_stem( &globals->blues,
@@ -382,7 +383,7 @@
             hint->cur_pos = align.align_top - fit_len;
             break;
           }
-          
+
         case PSH_BLUE_ALIGN_BOT:
           {
             /* the bottom of the stem is aligned against a blue zone */
@@ -389,7 +390,7 @@
             hint->cur_pos = align.align_bot;
             break;
           }
-          
+
         case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
           {
             /* both edges of the stem are aligned against blue zones */
@@ -397,26 +398,26 @@
             hint->cur_len = align.align_top - align.align_bot;
             break;
           }
-          
+
         default:
           {
             PSH2_Hint  parent = hint->parent;
-            
+
             if ( parent )
             {
               FT_Pos  par_org_center, par_cur_center;
               FT_Pos  cur_org_center, cur_delta;
-              
+
               /* ensure that parent is already fitted */
               if ( !psh2_hint_is_fitted(parent) )
                 psh2_hint_align( parent, globals, vertical );
-                
+
               par_org_center = parent->org_pos + (parent->org_len/2);
               par_cur_center = parent->cur_pos + (parent->cur_len/2);
-              cur_org_center = hint->org_pos + (hint->org_len/2);
-              
+              cur_org_center = hint->org_pos   + (hint->org_len/2);
+
               cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
-#if 0              
+#if 0
               if ( cur_delta >= 0 )
                 cur_delta = (cur_delta+16) & -64;
               else
@@ -436,19 +437,19 @@
               /* even number of pixels */
               fit_center = (pos + (len >> 1) + 32) & -64;
             }
-          
+
             hint->cur_pos = fit_center - (fit_len >> 1);
           }
       }
-      
+
       psh2_hint_set_fitted(hint);
-      
+
 #ifdef DEBUG_HINTER
       if (ps2_debug_hint_func)
         ps2_debug_hint_func( hint, vertical );
 #endif
     }
-  }                              
+  }
 
 
   static void
@@ -469,7 +470,7 @@
       ps2_simple_scale( table, scale, delta, vertical );
       return;
     }
-      
+
     if ( ps_debug_no_horz_hints && !vertical )
     {
       ps2_simple_scale( table, scale, delta, vertical );
@@ -491,7 +492,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
- 
+
 #define  PSH2_ZONE_MIN  -3200000
 #define  PSH2_ZONE_MAX  +3200000
 
@@ -527,9 +528,9 @@
     FT_UInt   count;
     PSH2_Zone  zone;
     PSH2_Hint *sort, hint, hint2;
-    
+
     zone  = table->zones;
-    
+
     /* special case, no hints defined */
     if ( table->num_hints == 0 )
     {
@@ -537,26 +538,26 @@
       zone->delta = delta;
       zone->min   = PSH2_ZONE_MIN;
       zone->max   = PSH2_ZONE_MAX;
-      
+
       table->num_zones = 1;
       table->zone      = zone;
       return;
     }
-    
+
     /* the first zone is before the first hint */
     /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
     sort  = table->sort;
     hint  = sort[0];
-    
+
     zone->scale = scale;
     zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
     zone->min   = PSH2_ZONE_MIN;
     zone->max   = hint->org_pos;
-    
+
     print_zone( zone );
-    
+
     zone++;
-    
+
     for ( count = table->num_hints; count > 0; count-- )
     {
       FT_Fixed  scale2;
@@ -566,7 +567,7 @@
         /* setup a zone for inner-stem interpolation */
         /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0)   */
         /* x' = x*s2 + x0' - x0*s2                   */
-        
+
         scale2      = FT_DivFix( hint->cur_len, hint->org_len );
         zone->scale = scale2;
         zone->min   = hint->org_pos;
@@ -574,16 +575,16 @@
         zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
 
         print_zone( zone );
-    
+
         zone++;
       }
-      
+
       if ( count == 1 )
         break;
-        
+
       sort++;
       hint2 = sort[0];
-      
+
       /* setup zone for inter-stem interpolation */
       /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1)     */
       /* x' = x*s3 + x1' - x1*s3                 */
@@ -595,9 +596,9 @@
       zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 );
 
       print_zone( zone );
-    
+
       zone++;
-      
+
       hint  = hint2;
     }
 
@@ -608,9 +609,9 @@
     zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale );
 
     print_zone( zone );
-    
+
     zone++;
-    
+
     table->num_zones = zone - table->zones;
     table->zone      = table->zones;
   }
@@ -617,15 +618,15 @@
 #endif
 
 #if 0
- /* tune a single coordinate with the current interpolation zones */  
+ /* tune a single coordinate with the current interpolation zones */
   static FT_Pos
   psh2_hint_table_tune_coord( PSH2_Hint_Table  table,
                               FT_Int           coord )
   {
     PSH2_Zone   zone;
-    
+
     zone = table->zone;
-      
+
     if ( coord < zone->min )
     {
       do
@@ -632,7 +633,7 @@
       {
         if ( zone == table->zones )
           break;
-          
+
         zone--;
       }
       while ( coord < zone->min );
@@ -644,13 +645,13 @@
       {
         if ( zone == table->zones + table->num_zones - 1 )
           break;
-          
+
         zone++;
       }
       while ( coord > zone->max );
       table->zone = zone;
     }
-        
+
     return FT_MulFix( coord, zone->scale ) + zone->delta;
   }
 #endif
@@ -671,7 +672,7 @@
     PSH_Dimension  dim        = &globals->dimension[vertical];
     FT_Fixed       scale      = dim->scale_mult;
     FT_Fixed       delta      = dim->scale_delta;
-    
+
     if ( hint_masks && hint_masks->num_masks > 0 )
     {
       first = 0;
@@ -680,30 +681,30 @@
       for ( ; count > 0; count--, mask++ )
       {
         last = mask->end_point;
-        
+
         if ( last > first )
         {
           FT_Vector*   vec;
           FT_Int       count2;
-          
+
           psh2_hint_table_activate_mask( table, mask );
           psh2_hint_table_optimize( table, globals, outline, vertical );
           psh2_hint_table_setup_zones( table, scale, delta );
           last = mask->end_point;
-          
+
           vec    = outline->points + first;
           count2 = last - first;
           for ( ; count2 > 0; count2--, vec++ )
           {
             FT_Pos  x, *px;
-            
+
             px  = vertical ? &vec->x : &vec->y;
             x   = *px;
-            
+
             *px = psh2_hint_table_tune_coord( table, (FT_Int)x );
           }
         }
-          
+
         first = last;
       }
     }
@@ -710,10 +711,10 @@
     else    /* no hints in this glyph, simply scale the outline */
     {
       FT_Vector*  vec;
-      
+
       vec   = outline->points;
       count = outline->n_points;
-      
+
       if ( vertical )
       {
         for ( ; count > 0; count--, vec++ )
@@ -749,17 +750,17 @@
       before = before->prev;
       if ( before == point )
         return 0;
-        
+
       d_before = before->org_u - point->org_u;
     }
     while ( d_before == 0 );
-    
+
     do
     {
       after = after->next;
       if ( after == point )
         return 0;
-        
+
       d_after = after->org_u - point->org_u;
     }
     while ( d_after == 0 );
@@ -777,7 +778,7 @@
 
     psh2_hint_table_done( &glyph->hint_tables[1], memory );
     psh2_hint_table_done( &glyph->hint_tables[0], memory );
-    
+
     FREE( glyph->points );
     FREE( glyph->contours );
 
@@ -793,10 +794,10 @@
   {
     FT_Pos  ax, ay;
     int     result = PSH2_DIR_NONE;
-    
+
     ax = ( dx >= 0 ) ? dx : -dx;
     ay = ( dy >= 0 ) ? dy : -dy;
-    
+
     if ( ay*12 < ax )
     {
       /* |dy| <<< |dx|  means a near-horizontal segment */
@@ -819,40 +820,40 @@
   {
     FT_Error   error;
     FT_Memory  memory;
-    
+
     /* clear all fields */
     memset( glyph, 0, sizeof(*glyph) );
-    
+
     memory = globals->memory;
-    
+
     /* allocate and setup points + contours arrays */
     if ( ALLOC_ARRAY( glyph->points,   outline->n_points,   PSH2_PointRec   ) ||
          ALLOC_ARRAY( glyph->contours, outline->n_contours, PSH2_ContourRec ) )
       goto Exit;
-    
+
     glyph->num_points   = outline->n_points;
     glyph->num_contours = outline->n_contours;
-    
+
     {
       FT_UInt       first = 0, next, n;
       PSH2_Point    points  = glyph->points;
       PSH2_Contour  contour = glyph->contours;
-      
+
       for ( n = 0; n < glyph->num_contours; n++ )
       {
         FT_Int      count;
         PSH2_Point  point;
-        
+
         next  = outline->contours[n] + 1;
         count = next - first;
-        
+
         contour->start = points + first;
         contour->count = (FT_UInt)count;
-        
+
         if ( count > 0 )
         {
           point = points + first;
-          
+
           point->prev    = points + next - 1;
           point->contour = contour;
           for ( ; count > 1; count-- )
@@ -865,7 +866,7 @@
           point->next = points + first;
         }
 
-        contour++; 
+        contour++;
         first = next;
       }
     }
@@ -875,19 +876,19 @@
       PSH2_Point  point  = points;
       FT_Vector*  vec    = outline->points;
       FT_UInt     n;
-      
+
       for ( n = 0; n < glyph->num_points; n++, point++ )
       {
         FT_Int    n_prev = point->prev - points;
         FT_Int    n_next = point->next - points;
         FT_Pos    dxi, dyi, dxo, dyo;
-        
+
         if ( !(outline->tags[n] & FT_Curve_Tag_On) )
           point->flags = PSH2_POINT_OFF;
-        
+
         dxi = vec[n].x - vec[n_prev].x;
         dyi = vec[n].y - vec[n_prev].y;
-        
+
         point->dir_in = (FT_Char) psh2_compute_dir( dxi, dyi );
 
         dxo = vec[n_next].x - vec[n].x;
@@ -894,7 +895,7 @@
         dyo = vec[n_next].y - vec[n].y;
 
         point->dir_out   = (FT_Char) psh2_compute_dir( dxo, dyo );
-        
+
         /* detect smooth points */
         if ( point->flags & PSH2_POINT_OFF )
         {
@@ -909,17 +910,17 @@
         else
         {
           FT_Angle  angle_in, angle_out, diff;
-          
+
           angle_in  = FT_Atan2( dxi, dyi );
           angle_out = FT_Atan2( dxo, dyo );
-          
+
           diff = angle_in - angle_out;
           if ( diff < 0 )
             diff = -diff;
-            
+
           if ( diff > FT_ANGLE_PI )
             diff = FT_ANGLE_2PI - diff;
-            
+
           if ( (diff < FT_ANGLE_PI/16) )
             point->flags |= PSH2_POINT_SMOOTH;
         }
@@ -937,7 +938,7 @@
                                   &ps_hints->dimension[0].counters,
                                   memory );
     if (error) goto Exit;
-    
+
     error = psh2_hint_table_init( &glyph->hint_tables [1],
                                   &ps_hints->dimension[1].hints,
                                   &ps_hints->dimension[1].masks,
@@ -944,7 +945,7 @@
                                   &ps_hints->dimension[1].counters,
                                   memory );
     if (error) goto Exit;
-    
+
   Exit:
     return error;
   }
@@ -967,15 +968,15 @@
         point->org_u = vec->x;
       else
         point->org_u = vec->y;
-        
+
 #ifdef DEBUG_HINTER
       point->org_x  = vec->x;
       point->org_y  = vec->y;
-#endif        
+#endif
     }
   }
 
-  
+
  /* save hinted point coordinates back to outline */
   static void
   psh2_glyph_save_points( PSH2_Glyph  glyph,
@@ -985,14 +986,14 @@
     PSH2_Point  point = glyph->points;
     FT_Vector*  vec   = glyph->outline->points;
     char*       tags  = glyph->outline->tags;
-    
+
     for ( n = 0; n < glyph->num_points; n++ )
-    { 
+    {
       if (vertical)
         vec[n].x = point->cur_u;
       else
         vec[n].y = point->cur_u;
-      
+
       if ( psh2_point_is_strong(point) )
         tags[n] |= vertical ? 32 : 64;
 
@@ -1007,12 +1008,14 @@
         point->cur_y   = point->cur_u;
         point->flags_y = point->flags;
       }
-#endif            
+#endif
       point++;
     }
   }
 
 
+#define  PSH2_STRONG_THRESHOLD  10
+
   static void
   psh2_hint_table_find_strong_point( PSH2_Hint_Table  table,
                                      PSH2_Point       point,
@@ -1020,18 +1023,18 @@
   {
     PSH2_Hint*   sort      = table->sort;
     FT_UInt      num_hints = table->num_hints;
-    
+
     for ( ; num_hints > 0; num_hints--, sort++ )
     {
       PSH2_Hint  hint = sort[0];
-      
+
       if ( ABS(point->dir_in)  == major_dir ||
            ABS(point->dir_out) == major_dir )
       {
         FT_Pos  d;
-        
+
         d = point->org_u - hint->org_pos;
-        if ( ABS(d) < 3 )
+        if ( ABS(d) < PSH2_STRONG_THRESHOLD )
         {
         Is_Strong:
           psh2_point_set_strong(point);
@@ -1038,13 +1041,13 @@
           point->hint = hint;
           break;
         }
-        
+
         d -= hint->org_len;
-        if ( ABS(d) < 3 )
+        if ( ABS(d) < PSH2_STRONG_THRESHOLD )
           goto Is_Strong;
       }
 
-#if 1              
+#if 1
       if ( point->org_u >= hint->org_pos &&
            point->org_u <= hint->org_pos + hint->org_len &&
            psh2_point_is_extremum( point ) )
@@ -1053,12 +1056,12 @@
         point->hint = hint;
         break;
       }
-#endif                
+#endif
     }
   }
-                                        
-                                         
 
+
+
  /* find strong points in a glyph */
   static void
   psh2_glyph_find_strong_points( PSH2_Glyph  glyph,
@@ -1071,8 +1074,8 @@
       PS_Mask          mask      = table->hint_masks->masks;
       FT_UInt          num_masks = table->hint_masks->num_masks;
       FT_UInt          first     = 0;
-      FT_Int           major_dir = vertical ? PSH2_DIR_UP    : PSH2_DIR_RIGHT;
-      
+      FT_Int           major_dir = vertical ? PSH2_DIR_UP : PSH2_DIR_RIGHT;
+
       /* process secondary hints to "selected" points */
       if ( num_masks > 1 )
       {
@@ -1081,15 +1084,15 @@
         {
           FT_UInt  next;
           FT_Int   count;
-          
+
           next  = mask->end_point;
           count = next - first;
           if ( count > 0 )
           {
             PSH2_Point  point = glyph->points + first;
-            
+
             psh2_hint_table_activate_mask( table, mask );
-            
+
             for ( ; count > 0; count--, point++ )
               psh2_hint_table_find_strong_point( table, point, major_dir );
           }
@@ -1096,13 +1099,13 @@
           first = next;
         }
       }
-      
+
       /* process primary hints for all points */
       if ( num_masks == 1 )
       {
         FT_UInt     count = glyph->num_points;
         PSH2_Point  point = glyph->points;
-        
+
         psh2_hint_table_activate_mask( table, table->hint_masks->masks );
         for ( ; count > 0; count--, point++ )
         {
@@ -1110,13 +1113,13 @@
             psh2_hint_table_find_strong_point( table, point, major_dir );
         }
       }
-      
+
       /* now, certain points may have been attached to hint and */
       /* not marked as strong, update their flags then..        */
       {
-        FT_UInt  count = glyph->num_points;
+        FT_UInt     count = glyph->num_points;
         PSH2_Point  point = glyph->points;
-        
+
         for ( ; count > 0; count--, point++ )
           if ( point->hint && !psh2_point_is_strong(point) )
             psh2_point_set_strong(point);
@@ -1137,32 +1140,32 @@
     {
       FT_UInt     count = glyph->num_points;
       PSH2_Point  point = glyph->points;
-      
+
       for ( ; count > 0; count--, point++ )
       {
         PSH2_Hint  hint = point->hint;
-        
+
         if ( hint )
         {
           FT_Pos  delta;
-          
+
           delta = point->org_u - hint->org_pos;
-          
+
           if ( delta <= 0 )
             point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );
-            
+
           else if ( delta >= hint->org_len )
             point->cur_u = hint->cur_pos + hint->cur_len +
                            FT_MulFix( delta - hint->org_len, scale );
-                           
+
           else if ( hint->org_len > 0 )
             point->cur_u = hint->cur_pos +
                            FT_MulDiv( delta, hint->cur_len, hint->org_len );
           else
             point->cur_u = hint->cur_pos;
-          
+
           psh2_point_set_fitted(point);
-        } 
+        }
       }
     }
   }
@@ -1180,12 +1183,12 @@
     {
       FT_UInt     count = glyph->num_points;
       PSH2_Point  point = glyph->points;
-      
+
       for ( ; count > 0; count--, point++ )
       {
         if ( psh2_point_is_strong(point) )
           continue;
-          
+
         /* sometimes, some local extremas are smooth points */
         if ( psh2_point_is_smooth(point) )
         {
@@ -1192,31 +1195,31 @@
           if ( point->dir_in == PSH2_DIR_NONE  ||
                point->dir_in != point->dir_out )
             continue;
-            
+
           if ( !psh2_point_is_extremum( point ) )
             continue;
-            
+
           point->flags &= ~PSH2_POINT_SMOOTH;
         }
-          
+
         /* find best enclosing point coordinates */
         {
           PSH2_Point  before = 0;
           PSH2_Point  after  = 0;
-          
+
           FT_Pos      diff_before = -32000;
           FT_Pos      diff_after  =  32000;
           FT_Pos      u = point->org_u;
-          
+
           FT_Int      count2 = glyph->num_points;
           PSH2_Point  cur    = glyph->points;
-          
+
           for ( ; count2 > 0; count2--, cur++ )
           {
             if ( psh2_point_is_strong(cur) )
             {
               FT_Pos   diff = cur->org_u - u;;
-              
+
               if ( diff <= 0 )
               {
                 if ( diff > diff_before )
@@ -1235,12 +1238,12 @@
               }
             }
           }
-          
+
           if ( !before )
           {
             if ( !after )
               continue;
-              
+
             /* we're before the first strong point coordinate */
             /* simply translate the point..                   */
             point->cur_u = after->cur_u +
@@ -1257,23 +1260,23 @@
           {
             if ( diff_before == 0 )
               point->cur_u = before->cur_u;
-              
+
             else if ( diff_after == 0 )
               point->cur_u = after->cur_u;
-              
+
             else
-              point->cur_u = before->cur_u + 
+              point->cur_u = before->cur_u +
                              FT_MulDiv( u - before->org_u,
                                         after->cur_u - before->cur_u,
                                         after->org_u - before->org_u );
           }
-          
+
           psh2_point_set_fitted(point);
         }
       }
     }
-#endif    
-  }  
+#endif
+  }
 
 
 
@@ -1287,27 +1290,27 @@
     FT_Fixed      delta        = dim->scale_delta;
     PSH2_Contour  contour      = glyph->contours;
     FT_UInt       num_contours = glyph->num_contours;
-    
+
     for ( ; num_contours > 0; num_contours--, contour++ )
     {
       PSH2_Point   start = contour->start;
       PSH2_Point   first, next, point;
       FT_UInt      fit_count;
-      
+
       /* count the number of strong points in this contour */
       next      = start + contour->count;
       fit_count = 0;
       first     = 0;
-      
+
       for ( point = start; point < next; point++ )
         if ( psh2_point_is_fitted(point) )
         {
           if ( !first )
             first = point;
-            
+
           fit_count++;
         }
-      
+
       /* if there is less than 2 fitted points in the contour, we'll */
       /* simply scale and eventually translate the contour points    */
       if ( fit_count < 2 )
@@ -1314,14 +1317,14 @@
       {
         if ( fit_count == 1 )
           delta = first->cur_u - FT_MulFix( first->org_u, scale );
-          
+
         for ( point = start; point < next; point++ )
           if ( point != first )
             point->cur_u = FT_MulFix( point->org_u, scale ) + delta;
-            
+
         goto Next_Contour;
       }
-              
+
       /* there are more than 2 strong points in this contour, we'll */
       /* need to interpolate weak points between them..             */
       start = first;
@@ -1328,20 +1331,20 @@
       do
       {
         point = first;
-        
+
         /* skip consecutive fitted points */
         for (;;)
         {
-          next = first->next; 
+          next = first->next;
           if ( next == start )
             goto Next_Contour;
-            
+
           if ( !psh2_point_is_fitted(next) )
             break;
-            
+
           first = next;
         }
-        
+
         /* find next fitted point after unfitted one */
         for (;;)
         {
@@ -1349,7 +1352,7 @@
           if ( psh2_point_is_fitted(next) )
             break;
         }
-        
+
         /* now interpolate between them */
         {
           FT_Pos    org_a, org_ab, cur_a, cur_ab;
@@ -1370,17 +1373,17 @@
             org_ab = first->org_u - org_a;
             cur_ab = first->cur_u - cur_a;
           }
-          
+
           scale_ab = 0x10000L;
           if ( org_ab > 0 )
             scale_ab = FT_DivFix( cur_ab, org_ab );
-            
+
           point = first->next;
           do
           {
             org_c  = point->org_u;
             org_ac = org_c - org_a;
-            
+
             if ( org_ac <= 0 )
             {
               /* on the left of the interpolation zone */
@@ -1392,28 +1395,28 @@
               cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale );
             }
             else
-            { 
+            {
               /* within the interpolation zone */
               cur_c = cur_a + FT_MulFix( org_ac, scale_ab );
             }
-            
+
             point->cur_u = cur_c;
-            
+
             point = point->next;
           }
           while ( point != next );
         }
-        
-        /* keep going until all points in the contours have been processed */  
+
+        /* keep going until all points in the contours have been processed */
         first = next;
       }
       while ( first != start );
-      
+
     Next_Contour:
       ;
     }
   }
-  
+
  /************************************************************************/
  /************************************************************************/
  /*****                                                              *****/
@@ -1421,7 +1424,7 @@
  /*****                                                              *****/
  /************************************************************************/
  /************************************************************************/
-  
+
   FT_Error
   ps2_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
@@ -1436,8 +1439,8 @@
     memory = globals->memory;
 
     FT_UNUSED(glyphrec);
-    
 
+
 #ifdef DEBUG_HINTER
     if ( ps2_debug_glyph )
     {
@@ -1444,23 +1447,23 @@
       psh2_glyph_done( ps2_debug_glyph );
       FREE( ps2_debug_glyph );
     }
-    
+
     if ( ALLOC( glyph, sizeof(*glyph) ) )
       return error;
-      
+
     ps2_debug_glyph = glyph;
-#else 
-    glyph = &glyphrec;    
+#else
+    glyph = &glyphrec;
 #endif
 
     error = psh2_glyph_init( glyph, outline, ps_hints, globals );
     if (error) goto Exit;
-    
+
     for ( dimension = 1; dimension >= 0; dimension-- )
     {
       /* load outline coordinates into glyph */
       psh2_glyph_load_points( glyph, dimension );
-      
+
       /* compute aligned stem/hints positions */
       psh2_hint_table_align_hints( &glyph->hint_tables[dimension],
                                    glyph->globals,
@@ -1471,13 +1474,13 @@
       psh2_glyph_interpolate_strong_points( glyph, dimension );
       psh2_glyph_interpolate_normal_points( glyph, dimension );
       psh2_glyph_interpolate_other_points( glyph, dimension );
-      
+
       /* save hinted coordinates back to outline */
       psh2_glyph_save_points( glyph, dimension );
     }
-    
-  Exit:    
-#ifndef DEBUG_HINTER  
+
+  Exit:
+#ifndef DEBUG_HINTER
     psh2_glyph_done( glyph );
 #endif
     return error;
--- a/src/pshinter/pshalgo2.h
+++ b/src/pshinter/pshalgo2.h
@@ -31,11 +31,11 @@
     PSH2_HINT_GHOST  = PS_HINT_FLAG_GHOST,
     PSH2_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM,
     PSH2_HINT_ACTIVE = 4,
-    PSH2_HINT_FITTED = 8  
+    PSH2_HINT_FITTED = 8
   } PSH2_Hint_Flags;
 
 #define  psh2_hint_is_active(x)  (((x)->flags  & PSH2_HINT_ACTIVE) != 0)
-#define  psh2_hint_is_ghost(x)   (((x)->flags  & PSH2_HINT_GHOST)  != 0)  
+#define  psh2_hint_is_ghost(x)   (((x)->flags  & PSH2_HINT_GHOST)  != 0)
 #define  psh2_hint_is_fitted(x)  (((x)->flags  & PSH2_HINT_FITTED) != 0)
 
 #define  psh2_hint_activate(x)     (x)->flags |=  PSH2_HINT_ACTIVE
@@ -51,7 +51,7 @@
     FT_UInt    flags;
     PSH2_Hint  parent;
     FT_Int     order;
-  
+
   } PSH2_HintRec;
 
 
@@ -64,7 +64,7 @@
     FT_Fixed  delta;
     FT_Pos    min;
     FT_Pos    max;
-    
+
   } PSH2_ZoneRec, *PSH2_Zone;
 
 
@@ -80,12 +80,13 @@
     PSH2_Zone      zone;
     PS_Mask_Table  hint_masks;
     PS_Mask_Table  counter_masks;
-    
+
   } PSH2_Hint_TableRec, *PSH2_Hint_Table;
 
+
   typedef struct PSH2_PointRec_*    PSH2_Point;
   typedef struct PSH2_ContourRec_*  PSH2_Contour;
-  
+
   enum
   {
     PSH2_DIR_NONE   =  4,
@@ -94,7 +95,7 @@
     PSH2_DIR_LEFT   = -2,
     PSH2_DIR_RIGHT  =  2
   };
-  
+
   enum
   {
     PSH2_POINT_OFF    = 1,   /* point is off the curve  */
@@ -124,10 +125,11 @@
     FT_Pos        cur_y;
     FT_UInt       flags_x;
     FT_UInt       flags_y;
-#endif    
-    
+#endif
+
   } PSH2_PointRec;
 
+
 #define  psh2_point_is_strong(p)   ((p)->flags & PSH2_POINT_STRONG)
 #define  psh2_point_is_fitted(p)   ((p)->flags & PSH2_POINT_FITTED)
 #define  psh2_point_is_smooth(p)   ((p)->flags & PSH2_POINT_SMOOTH)
@@ -140,37 +142,37 @@
   {
     PSH2_Point  start;
     FT_UInt     count;
-   
+
   } PSH2_ContourRec;
 
-  
 
+
   typedef struct PSH2_GlyphRec_
   {
     FT_UInt             num_points;
     FT_UInt             num_contours;
-    
+
     PSH2_Point          points;
     PSH2_Contour        contours;
-               
+
     FT_Memory           memory;
     FT_Outline*         outline;
     PSH_Globals         globals;
     PSH2_Hint_TableRec  hint_tables[2];
-    
+
     FT_Bool             vertical;
     FT_Int              major_dir;
     FT_Int              minor_dir;
-    
+
   } PSH2_GlyphRec, *PSH2_Glyph;
 
 
-#ifdef DEBUG_HINTER  
+#ifdef DEBUG_HINTER
   extern  PSH2_Hint_Table  ps2_debug_hint_table;
 
   typedef void  (*PSH2_HintFunc)( PSH2_Hint  hint, FT_Bool vertical );
   extern  PSH2_HintFunc    ps2_debug_hint_func;
-  
+
   extern  PSH2_Glyph       ps2_debug_glyph;
 #endif
 
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -1009,9 +1009,9 @@
       }
     }
 
-#ifdef DEBUG_VIEW
+#ifdef DEBUG_HINTER
     if (!error)
-      the_ps_hints = hints;
+      ps_debug_hints = hints;
 #endif
     return error;
   }
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -86,7 +86,7 @@
 
 
 /* experimental support for gamma correction within the rasterizer */
-#define  GRAYS_USE_GAMMA
+#define  xxxGRAYS_USE_GAMMA
 
   /*************************************************************************/
   /*                                                                       */
@@ -209,7 +209,7 @@
   /*                                                                       */
   /*   TYPE DEFINITIONS                                                    */
   /*                                                                       */
-  
+
   /* don't change the following types to FT_Int or FT_Pos, since we might */
   /* need to define them to "float" or "double" when experimenting with   */
   /* new algorithms                                                       */
@@ -220,7 +220,7 @@
   /* determine the type used to store cell areas.  This normally takes at */
   /* least PIXEL_BYTES*2 + 1.  On 16-bit systems, we need to use `long'   */
   /* instead of `int', otherwise bad things happen                        */
- 
+
 #if PIXEL_BITS <= 7
 
   typedef int   TArea;
@@ -1181,9 +1181,9 @@
     /* start to a new position */
     x = UPSCALE( to->x );
     y = UPSCALE( to->y );
-    
+
     gray_start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) );
-      
+
     ((PRaster)raster)->x = x;
     ((PRaster)raster)->y = y;
     return 0;
@@ -1243,7 +1243,7 @@
 #ifdef GRAYS_USE_GAMMA
       coverage = raster->gamma[(FT_Byte)coverage];
 #endif
-      
+
       if ( coverage )
 #if 1
         MEM_Set( p + spans->x, (unsigned char)coverage, spans->len );
@@ -1400,7 +1400,7 @@
 
     if ( ras.num_cells == 0 )
       return;
-      
+
     cur   = ras.cells;
     limit = cur + ras.num_cells;
 
@@ -1748,7 +1748,7 @@
     };
 
     volatile int  error = 0;
-    
+
     if ( setjmp( ras.jump_buffer ) == 0 )
     {
       error = FT_Outline_Decompose( &ras.outline, &interface, &ras );
@@ -1778,7 +1778,7 @@
 
     /* clip to target bitmap, exit if nothing to do */
     clip = &ras.clip_box;
-    
+
     if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
          ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
       return 0;
@@ -1841,7 +1841,7 @@
 
 #if 1
         error = gray_convert_glyph_inner( RAS_VAR );
-#else       
+#else
         error = FT_Outline_Decompose( outline, &interface, &ras ) ||
                 gray_record_cell( RAS_VAR );
 #endif
@@ -1987,7 +1987,7 @@
   grays_init_gamma( PRaster  raster )
   {
     FT_UInt  x, a;
-    
+
     for ( x = 0; x < 256; x++ )
     {
       if ( x <= M_X )
@@ -1994,11 +1994,11 @@
         a = (x * M_Y + (M_X/2)) / M_X;
       else
         a = M_Y + ((x-M_X)*(M_MAX-M_Y) + (M_MAX-M_X)/2)/(M_MAX-M_X);
-      
+
       raster->gamma[x] = (FT_Byte)a;
     }
   }
-  
+
 #endif /* GRAYS_USE_GAMMA */
 
 #ifdef _STANDALONE_
@@ -2018,7 +2018,7 @@
 #ifdef GRAYS_USE_GAMMA
     grays_init_gamma( (PRaster)*araster );
 #endif
-    
+
     return 0;
   }
 
--- a/tests/gview.c
+++ b/tests/gview.c
@@ -74,6 +74,7 @@
 static  int   option_show_edges    = 0;
 static  int   option_show_segments = 1;
 static  int   option_show_links    = 1;
+static  int   option_show_indices  = 0;
 
 static  int   option_show_ps_hints   = 1;
 static  int   option_show_horz_hints = 1;
@@ -112,7 +113,7 @@
 #define  EDGE_COLOR        0xF0704070
 #define  SEGMENT_COLOR     0xF0206040
 #define  LINK_COLOR        0xF0FFFF00
-#define  SERIF_LINK_COLOR  0xF0FF808F  
+#define  SERIF_LINK_COLOR  0xF0FF808F
 
 /* print message and abort program */
 static void
@@ -160,15 +161,15 @@
 
 static void
 reset_scale( NV_Scale  scale )
-{ 
+{
  /* compute font units -> grid pixels scale factor */
   glyph_scale = target->width*0.75 / face->units_per_EM * scale;
- 
+
  /* setup font units -> grid pixels transform */
   nv_transform_set_scale( &glyph_transform, glyph_scale, -glyph_scale );
   glyph_org_x = glyph_transform.delta.x = target->width*0.125;
   glyph_org_y = glyph_transform.delta.y = target->height*0.875;
- 
+
  /* setup subpixels -> grid pixels transform */
   nv_transform_set_scale( &size_transform,
                             glyph_scale/nv_fromfixed(face->size->metrics.x_scale),
@@ -176,8 +177,8 @@
 
   size_transform.delta = glyph_transform.delta;
 }
-           
-           
+
+
 static void
 reset_size( int  pixel_size, NV_Scale  scale )
 {
@@ -204,7 +205,7 @@
   if ( option_show_grid )
   {
     NV_Scale  min, max, x, step;
-    
+
     /* draw vertical grid bars */
     step = 64. * size_transform.matrix.xx;
     if (step > 1.)
@@ -212,12 +213,12 @@
       min  = max = glyph_org_x;
       while ( min - step >= 0 )             min -= step;
       while ( max + step < target->width )  max += step;
-        
+
       for ( x = min; x <= max; x += step )
         nv_pixmap_fill_rect( target, (NV_Int)(x+.5), 0,
                              1, target->height, GRID_COLOR );
     }
-                                
+
     /* draw horizontal grid bars */
     step = -64. * size_transform.matrix.yy;
     if (step > 1.)
@@ -225,13 +226,13 @@
       min  = max = glyph_org_y;
       while ( min - step >= 0 )              min -= step;
       while ( max + step < target->height )  max += step;
-        
+
       for ( x = min; x <= max; x += step )
         nv_pixmap_fill_rect( target, 0, (NV_Int)(x+.5),
                              target->width, 1, GRID_COLOR );
     }
-  }  
-  
+  }
+
   /* draw axis */
   if ( option_show_axis )
   {
@@ -238,16 +239,16 @@
     nv_pixmap_fill_rect( target, x, 0, 1, target->height, AXIS_COLOR );
     nv_pixmap_fill_rect( target, 0, y, target->width, 1, AXIS_COLOR );
   }
-  
+
   if ( option_show_em )
   {
     NV_Path  path;
     NV_Path  stroke;
     NV_UInt  units = (NV_UInt)face->units_per_EM;
-    
+
     nv_path_new_rectangle( renderer, 0, 0, units, units, 0, 0, &path );
     nv_path_transform( path, &glyph_transform );
-    
+
     nv_path_stroke( path, 1.5, nv_path_linecap_butt, nv_path_linejoin_miter,
                     4.0, &stroke );
 
@@ -282,12 +283,12 @@
     FT_Int          y1, y2;
     FT_UInt         count;
     PSH_Blue_Zone   zone;
-    
+
     /* draw top zones */
     table = &blues->normal_top;
     count = table->count;
     zone  = table->zones;
-    
+
     for ( ; count > 0; count--, zone++ )
     {
       v.x = 0;
@@ -302,7 +303,7 @@
         nv_vector_transform( &v, &glyph_transform );
       }
       y1  = (int)(v.y + 0.5);
-      
+
       v.x = 0;
       if ( !ps_debug_no_horz_hints )
       {
@@ -315,22 +316,22 @@
         nv_vector_transform( &v, &glyph_transform );
       }
       y2 = (int)(v.y + 0.5);
-      
+
       nv_pixmap_fill_rect( target, 0, y1,
                            target->width, y2-y1+1,
                            BLUES_TOP_COLOR );
 
-#if 0                           
+#if 0
       printf( "top [%.3f %.3f]\n", zone->cur_bottom/64.0, zone->cur_top/64.0 );
-#endif      
+#endif
     }
-    
-    
+
+
     /* draw bottom zones */
     table = &blues->normal_bottom;
     count = table->count;
     zone  = table->zones;
-    
+
     for ( ; count > 0; count--, zone++ )
     {
       v.x = 0;
@@ -337,12 +338,12 @@
       v.y = zone->cur_ref;
       nv_vector_transform( &v, &size_transform );
       y1  = (int)(v.y + 0.5);
-      
+
       v.x = 0;
       v.y = zone->cur_ref + zone->cur_delta;
       nv_vector_transform( &v, &size_transform );
       y2 = (int)(v.y + 0.5);
-      
+
       nv_pixmap_fill_rect( target, 0, y1,
                            target->width, y2-y1+1,
                            BLUES_BOT_COLOR );
@@ -372,8 +373,8 @@
 {
   int        x1, x2;
   NV_Vector  v;
-  
-  
+
+
   if ( pshint_vertical != vertical )
   {
     if (vertical)
@@ -380,15 +381,15 @@
       pshint_cpos = 40;
     else
       pshint_cpos = 10;
-      
+
     pshint_vertical = vertical;
   }
-  
+
   if (vertical)
   {
     if ( !option_show_vert_hints )
       return;
-      
+
     v.x = hint->cur_pos;
     v.y = 0;
     nv_vector_transform( &v, &size_transform );
@@ -420,7 +421,7 @@
   {
     if (!option_show_horz_hints)
       return;
-      
+
     v.y = hint->cur_pos;
     v.x = 0;
     nv_vector_transform( &v, &size_transform );
@@ -452,7 +453,7 @@
 #if 0
   printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
 #endif
-  
+
   pshint_cpos += 10;
 }
 
@@ -473,7 +474,7 @@
 {
   int        x1, x2;
   NV_Vector  v;
-  
+
   if ( pshint_vertical != vertical )
   {
     if (vertical)
@@ -480,15 +481,15 @@
       pshint_cpos = 40;
     else
       pshint_cpos = 10;
-      
+
     pshint_vertical = vertical;
   }
-  
+
   if (vertical)
   {
     if ( !option_show_vert_hints )
       return;
-      
+
     v.x = hint->cur_pos;
     v.y = 0;
     nv_vector_transform( &v, &size_transform );
@@ -520,7 +521,7 @@
   {
     if (!option_show_horz_hints)
       return;
-      
+
     v.y = hint->cur_pos;
     v.x = 0;
     nv_vector_transform( &v, &size_transform );
@@ -552,7 +553,7 @@
 #if 0
   printf( "[%7.3f %7.3f] %c\n", hint->cur_pos/64.0, (hint->cur_pos+hint->cur_len)/64.0, vertical ? 'v' : 'h' );
 #endif
-  
+
   pshint_cpos += 10;
 }
 
@@ -569,15 +570,15 @@
     NV_Path       vert_rect;
     NV_Path       horz_rect;
     NV_Path       dot, circle;
-    
+
     for ( ; count > 0; count--, point++ )
     {
       NV_Vector  vec;
-      
+
       vec.x = point->cur_x;
       vec.y = point->cur_y;
       nv_vector_transform( &vec, &size_transform );
-      
+
       nv_transform_set_translate( trans, vec.x, vec.y );
 
       if ( option_show_smooth && !psh2_point_is_smooth(point) )
@@ -585,7 +586,7 @@
         nv_painter_set_color( painter, SMOOTH_COLOR, 256 );
         nv_painter_fill_path( painter, trans, 0, symbol_circle );
       }
-        
+
       if (option_show_horz_hints)
       {
         if ( point->flags_y & PSH2_POINT_STRONG )
@@ -594,7 +595,7 @@
           nv_painter_fill_path( painter, trans, 0, symbol_rect_h );
         }
       }
-      
+
       if (option_show_vert_hints)
       {
         if ( point->flags_x & PSH2_POINT_STRONG )
@@ -607,6 +608,44 @@
   }
 }
 
+
+static void
+ps_print_hints( void )
+{
+  if ( ps_debug_hints )
+  {
+    FT_Int         dimension;
+    PSH_Dimension  dim;
+
+    for ( dimension = 1; dimension >= 0; dimension-- )
+    {
+      PS_Dimension  dim   = &ps_debug_hints->dimension[ dimension ];
+      PS_Mask       mask  = dim->masks.masks;
+      FT_UInt       count = dim->masks.num_masks;
+
+      printf( "%s hints -------------------------\n",
+              dimension ? "vertical" : "horizontal" );
+
+      for ( ; count > 0; count--, mask++ )
+      {
+        FT_UInt  index;
+
+        printf( "mask -> %d\n", mask->end_point );
+        for ( index = 0; index < mask->num_bits; index++ )
+        {
+          if ( mask->bytes[ index >> 3 ] & (0x80 >> (index & 7)) )
+          {
+            PS_Hint  hint = dim->hints.hints + index;
+
+            printf( "%c [%3d %3d (%4d)]\n", dimension ? "v" : "h",
+                    hint->pos, hint->pos + hint->len, hint->len );
+          }
+        }
+      }
+    }
+  }
+}
+
  /************************************************************************/
  /************************************************************************/
  /*****                                                              *****/
@@ -628,7 +667,7 @@
   {
     p2.x = p4->x;
     p2.y = p1->y;
-    
+
     p3.x = p1->x;
     p3.y = p4->y;
   }
@@ -636,25 +675,25 @@
   {
     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
@@ -665,9 +704,9 @@
     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 ) )
@@ -674,11 +713,11 @@
       {
         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 );
       }
@@ -696,7 +735,7 @@
     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 )
@@ -703,7 +742,7 @@
     {
       /* draw verticla edges */
       if ( option_show_vert_hints )
-      {    
+      {
         count = glyph->num_vedges;
         edge  = glyph->vert_edges;
         for ( ; count > 0; count--, edge++ )
@@ -710,17 +749,17 @@
         {
           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 )
       {
@@ -730,18 +769,18 @@
         {
           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 */
@@ -749,18 +788,18 @@
       {
         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;
@@ -771,35 +810,35 @@
             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;
@@ -810,14 +849,14 @@
             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 );
         }
       }
@@ -827,13 +866,13 @@
       {
         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 )
@@ -841,7 +880,7 @@
           }
           else if ( seg->serif )
             seg2 = seg->serif;
-          
+
           if ( seg2 )
           {
             v1.x = seg->first->x  - pp1;
@@ -848,12 +887,12 @@
             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 );
           }
         }
@@ -863,13 +902,13 @@
       {
         AH_Segment*  seg   = glyph->horz_segments;
         FT_UInt      count = glyph->num_hsegments;
-        
+
         for ( ; count > 0; count--, seg++ )
         {
           AH_Segment*  seg2 = NULL;
           NV_Path      link;
           NV_Vector    v1, v2;
-          
+
           if ( seg->link )
           {
             if ( seg->link > seg )
@@ -877,7 +916,7 @@
           }
           else if ( seg->serif )
             seg2 = seg->serif;
-          
+
           if ( seg2 )
           {
             v1.y = seg->first->y;
@@ -884,12 +923,12 @@
             v2.y = seg2->first->y;
             v1.x = (seg->first->x + seg->last->x)/2 - pp1;
             v2.x = (seg2->first->x + seg2->last->x)/2 - pp1;
-            
+
             link = ah_link_path( &v1, &v2, 0 );
-            
+
             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 );
           }
         }
@@ -912,7 +951,7 @@
   NV_Path   path;
 
   pshint_vertical    = -1;
-  
+
   ps1_debug_hint_func = option_show_ps_hints ? draw_ps1_hint : 0;
   ps2_debug_hint_func = option_show_ps_hints ? draw_ps2_hint : 0;
 
@@ -922,16 +961,16 @@
                                           ? FT_LOAD_NO_BITMAP
                                           : FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING );
   if (error) Panic( "could not load glyph" );
-  
+
   if ( face->glyph->format != ft_glyph_format_outline )
     Panic( "could not load glyph outline" );
-  
+
   error = nv_path_new_from_outline( renderer,
                                     (NV_Outline*)&face->glyph->outline,
                                     &size_transform,
                                     &path );
   if (error) Panic( "could not create glyph path" );
-  
+
   /* trac� du glyphe plein */
   if ( option_show_glyph )
   {
@@ -942,16 +981,16 @@
   if ( option_show_stroke )
   {
     NV_Path   stroke;
-    
+
     error = nv_path_stroke( path, 0.6,
                             nv_path_linecap_butt,
                             nv_path_linejoin_miter,
                             1.0, &stroke );
     if (error) Panic( "could not stroke glyph path" );
-  
+
     nv_painter_set_color ( painter, 0xFF000040, 256 );
     nv_painter_fill_path ( painter, 0, 0, stroke );
-  
+
     nv_path_destroy( stroke );
   }
 
@@ -964,7 +1003,7 @@
     NV_Int      n, first, last;
 
     nv_path_get_outline( path, NULL, memory, &out );
-    
+
     first = 0;
     for ( n = 0; n < out.n_contours; n++ )
     {
@@ -972,24 +1011,32 @@
       NV_Transform   trans;
       NV_Color       color;
       NV_SubVector*  vec;
-      
+
       last  = out.contours[n];
-      
+
       for ( m = first; m <= last; m++ )
       {
         color = (out.tags[m] & FT_Curve_Tag_On)
               ? ON_COLOR
               : OFF_COLOR;
-              
+
         vec = out.points + m;
 
-        nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 );        
+        nv_transform_set_translate( &trans, vec->x/64.0, vec->y/64.0 );
 
         nv_painter_set_color( painter, color, 256 );
         nv_painter_fill_path( painter, &trans, 0, symbol_dot );
 
+        if ( option_show_indices )
+        {
+          char  temp[5];
+
+          sprintf( temp, "%d", m );
+          nv_pixmap_cell_text( target, vec->x/64 + 4, vec->y/64 - 4,
+                               temp, TEXT_COLOR );
+        }
       }
-      
+
       first = last + 1;
     }
   }
@@ -996,23 +1043,23 @@
 
   ah_draw_smooth_points();
   ah_draw_edges();
-  
+
   nv_path_destroy( path );
-  
+
   /* autre infos */
   {
     char  temp[1024];
     char  temp2[64];
-    
+
     sprintf( temp, "font name : %s (%s)", face->family_name, face->style_name );
     nv_pixmap_cell_text( target, 0, 0, temp, TEXT_COLOR );
-    
+
     FT_Get_Glyph_Name( face, glyph_index, temp2, 63 );
     temp2[63] = 0;
-    
+
     sprintf( temp, "glyph %4d: %s", glyph_index, temp2 );
     nv_pixmap_cell_text( target, 0, 8, temp, TEXT_COLOR );
-    
+
     if ( temp_message[0] )
     {
       nv_pixmap_cell_text( target, 0, 16, temp_message, TEXT_COLOR );
@@ -1040,7 +1087,7 @@
               break;                                         \
             }
 
-            
+
 static void
 handle_event( NVV_EventRec*   ev )
 {
@@ -1065,16 +1112,16 @@
 
     case NVV_KEY('s'):
       TOGGLE_OPTION( option_show_stroke, "glyph stroke display" )
-    
+
     case NVV_KEY('g'):
       TOGGLE_OPTION( option_show_glyph, "glyph fill display" )
-      
+
     case NVV_KEY('d'):
       TOGGLE_OPTION( option_show_dots, "control points display" )
-      
+
     case NVV_KEY('e'):
       TOGGLE_OPTION( option_show_em, "EM square display" )
-    
+
     case NVV_KEY('+'):
       {
         grid_scale *= 1.2;
@@ -1081,7 +1128,7 @@
         reset_scale( grid_scale );
         break;
       }
-      
+
     case NVV_KEY('-'):
       {
         if (grid_scale > 0.3)
@@ -1126,12 +1173,19 @@
     case NVV_KEY('S'):
       TOGGLE_OPTION( option_show_smooth, "smooth points display" );
 
+    case NVV_KEY('i'):
+      TOGGLE_OPTION( option_show_indices, "point index display" );
+
     case NVV_KEY('b'):
       TOGGLE_OPTION( option_show_blues, "blue zones display" );
 
     case NVV_KEY('h'):
       TOGGLE_OPTION( option_hinting, "hinting" )
-      
+
+    case NVV_KEY('H'):
+      ps_print_hints();
+      break;
+
     default:
       ;
   }
@@ -1166,7 +1220,7 @@
 {
   int    argc = *argc_p;
   char** argv = *argv_p;
-  
+
   while (argc > 2 && argv[1][0] == '-')
   {
     switch (argv[1][1])
@@ -1174,28 +1228,28 @@
       OPTION2( 'f', first_glyph = atoi( argv[2] ); )
 
       OPTION2( 's', pixel_size = atoi( argv[2] ); )
-      
+
       default:
         usage();
     }
   }
-  
+
   *argc_p = argc;
   *argv_p = argv;
 }
-  
-  
 
+
+
 int  main( int  argc, char**  argv )
 {
   char*  filename = "/winnt/fonts/arial.ttf";
-  
+
   parse_options( &argc, &argv );
-  
+
   if ( argc >= 2 )
     filename = argv[1];
-   
-  
+
+
   /* create library */
   error = nv_renderer_new( 0, &renderer );
   if (error) Panic( "could not create Nirvana renderer" );
@@ -1205,7 +1259,7 @@
 
   error = nvv_display_new( renderer, &display );
   if (error) Panic( "could not create display" );
-  
+
   error = nvv_surface_new( display, 460, 460, nv_pixmap_type_argb, &surface );
   if (error) Panic( "could not create surface" );
 
@@ -1213,26 +1267,26 @@
 
   error = nv_painter_new( renderer, &painter );
   if (error) Panic( "could not create painter" );
-  
+
   nv_painter_set_target( painter, target );
-  
+
   clear_background();
 
   error = FT_Init_FreeType( &freetype );
   if (error) Panic( "could not initialise FreeType" );
-  
+
   error = FT_New_Face( freetype, filename, 0, &face );
   if (error) Panic( "could not open font face" );
 
   reset_size( pixel_size, grid_scale );
- 
 
+
   nvv_surface_set_title( surface, "FreeType Glyph Viewer" );
 
   {
     NVV_EventRec  event;
 
-    glyph_index = first_glyph;    
+    glyph_index = first_glyph;
     for ( ;; )
     {
       clear_background();
@@ -1247,29 +1301,29 @@
       draw_ps_blue_zones();
       draw_glyph( glyph_index );
       ps2_draw_control_points();
-      
+
       nvv_surface_refresh( surface, NULL );
 
       nvv_surface_listen( surface, 0, &event );
       if ( event.key == NVV_Key_Esc )
         break;
-        
+
       handle_event( &event );
       switch (event.key)
       {
         case NVV_Key_Esc:
           goto Exit;
-          
+
         default:
           ;
       }
     }
   }
- 
+
  Exit:
   /* wait for escape */
-      
-  
+
+
   /* destroy display (and surface) */
   nvv_display_unref( display );