Commit 8cfb220eb976949396a4949320424e8c4e9fb19d

Wu, Chia-I (吳佳一) 2005-06-20T09:04:50

* include/freetype/internal/ftobjs.h, src/base/ftobjs.c: New function ft_glyphslot_grid_fit_metrics. * src/truetype/ttgload.c (compute_glyph_metrics): Use ft_glyphslot_grid_fit_metrics. * src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c (cid_slot_load_glyph), src/type1/t1gload.c (T1_Load_Glyph): Use ft_glyphslot_grid_fit_metrics. FT_Outline_Get_CBox is called twice. * src/base/ftsynth.c (FT_GlyphSlot_Embolden): Modify metrics to more reasonable values when emboldening outline glyphs. The theoretic ones are unrealistic.

diff --git a/ChangeLog b/ChangeLog
index 742241d..99ac8d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-06-20  Chia I Wu  <b90201047@ntu.edu.tw>
+
+	* include/freetype/internal/ftobjs.h, src/base/ftobjs.c: New function
+	ft_glyphslot_grid_fit_metrics.
+
+	* src/truetype/ttgload.c (compute_glyph_metrics): Use
+	ft_glyphslot_grid_fit_metrics.
+	
+	* src/cff/cffgload.c (cff_slot_load), src/cid/cidgload.c
+	(cid_slot_load_glyph), src/type1/t1gload.c (T1_Load_Glyph): Use
+	ft_glyphslot_grid_fit_metrics.
+	FT_Outline_Get_CBox is called twice.
+
+	* src/base/ftsynth.c (FT_GlyphSlot_Embolden): Modify metrics to more
+	reasonable values when emboldening outline glyphs.  The theoretic
+	ones are unrealistic.
+
 2005-06-16  Chia I Wu  <b90201047@ntu.edu.tw>
 
 	* src/base/ftoutln.c (FT_Outline_Embolden): Strength should be
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index e8e3ee7..317c2f0 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -452,6 +452,13 @@ FT_BEGIN_HEADER
  /* */
 
  /*
+  * grid-fit slot->metrics
+  */
+  FT_BASE( void )
+  ft_glyphslot_grid_fit_metrics( FT_GlyphSlot  slot );
+
+
+ /*
   * Free the bitmap of a given glyphslot when needed
   * (i.e., only when it was allocated with ft_glyphslot_alloc_bitmap).
   */
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 1bf813a..4a4fc04 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -251,6 +251,29 @@
 
 
   FT_BASE_DEF( void )
+  ft_glyphslot_grid_fit_metrics( FT_GlyphSlot  slot )
+  {
+    FT_Pos  tmp;
+
+
+    tmp = FT_PIX_CEIL( slot->metrics.horiBearingX + slot->metrics.width );
+    slot->metrics.horiBearingX = FT_PIX_FLOOR( slot->metrics.horiBearingX );
+    slot->metrics.width        = tmp - slot->metrics.horiBearingX;
+
+    tmp = FT_PIX_FLOOR( slot->metrics.horiBearingY - slot->metrics.height );
+    slot->metrics.horiBearingY = FT_PIX_CEIL( slot->metrics.horiBearingY );
+    slot->metrics.height       = slot->metrics.horiBearingY - tmp;
+
+    slot->metrics.horiAdvance  = FT_PIX_ROUND( slot->metrics.horiAdvance );
+
+    slot->metrics.vertBearingX = FT_PIX_FLOOR( slot->metrics.vertBearingX );
+    /* note that vertBearinY should be floor'ed */
+    slot->metrics.vertBearingY = FT_PIX_FLOOR( slot->metrics.vertBearingY );
+    slot->metrics.vertAdvance  = FT_PIX_ROUND( slot->metrics.vertAdvance );
+  }
+
+
+  FT_BASE_DEF( void )
   ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,
                            FT_Byte*      buffer )
   {
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index ed80951..c2d4d52 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -87,7 +87,10 @@
     if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
     {
       error = FT_Outline_Embolden( &slot->outline, xstr );
-      xstr = xstr * 4;  /* according to the documentation */
+
+      /* this is more than enough for most glyphs                     */
+      /* if you need accurate values, you have to FT_Outline_Get_CBox */
+      xstr = xstr * 2;
       ystr = xstr;
     }
     else if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 3c0ef6b..03458cd 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -2510,11 +2510,8 @@
         glyph->root.linearHoriAdvance           = decoder.glyph_width;
         glyph->root.internal->glyph_transformed = 0;
 
-        /* make up vertical metrics */
-        metrics->vertBearingX = 0;
-        metrics->vertBearingY = 0;
+        /* make up vertical ones */
         metrics->vertAdvance  = 0;
-
         glyph->root.linearVertAdvance = 0;
 
         glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
@@ -2559,42 +2556,26 @@
               vec->y = FT_MulFix( vec->y, y_scale );
             }
 
-          FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
-
           /* Then scale the metrics */
           metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,  x_scale );
           metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  y_scale );
-
-          metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
-          metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
-
-          if ( hinting )
-          {
-            metrics->horiAdvance  = FT_PIX_ROUND( metrics->horiAdvance );
-            metrics->vertAdvance  = FT_PIX_ROUND( metrics->vertAdvance );
-
-            metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX );
-            metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY );
-          }
         }
 
         /* compute the other metrics */
         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
 
-        /* grid fit the bounding box if necessary */
-        if ( hinting )
-        {
-          cbox.xMin &= -64;
-          cbox.yMin &= -64;
-          cbox.xMax  = ( cbox.xMax + 63 ) & -64;
-          cbox.yMax  = ( cbox.yMax + 63 ) & -64;
-        }
-
         metrics->width  = cbox.xMax - cbox.xMin;
         metrics->height = cbox.yMax - cbox.yMin;
 
         metrics->horiBearingX = cbox.xMin;
         metrics->horiBearingY = cbox.yMax;
+
+        /* make up vertical ones */
+        metrics->vertBearingX = 0;
+        metrics->vertBearingY = 0;
+
+        if ( hinting )
+          ft_glyphslot_grid_fit_metrics( &glyph->root );
       }
     }
 
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index cbd0865..b084d44 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -358,12 +358,10 @@
         cidglyph->linearHoriAdvance           = decoder.builder.advance.x;
         cidglyph->internal->glyph_transformed = 0;
 
-        /* make up vertical metrics */
-        metrics->vertBearingX = 0;
-        metrics->vertBearingY = 0;
+        /* make up vertical ones */
         metrics->vertAdvance  = 0;
-
         cidglyph->linearVertAdvance = 0;
+
         cidglyph->format            = FT_GLYPH_FORMAT_OUTLINE;
 
         if ( size && cidsize->metrics.y_ppem < 24 )
@@ -403,42 +401,26 @@
               vec->y = FT_MulFix( vec->y, y_scale );
             }
 
-          FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
-
           /* Then scale the metrics */
           metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,  x_scale );
           metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  y_scale );
-
-          metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
-          metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
-
-          if ( hinting )
-          {
-            metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
-            metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
-
-            metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX );
-            metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY );
-          }
         }
 
         /* compute the other metrics */
         FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
 
-        /* grid fit the bounding box if necessary */
-        if ( hinting )
-        {
-          cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
-          cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
-          cbox.xMax = FT_PIX_CEIL( cbox.xMax );
-          cbox.yMax = FT_PIX_CEIL( cbox.yMax );
-        }
-
         metrics->width  = cbox.xMax - cbox.xMin;
         metrics->height = cbox.yMax - cbox.yMin;
 
         metrics->horiBearingX = cbox.xMin;
         metrics->horiBearingY = cbox.yMax;
+
+        /* make up vertical ones */
+        metrics->vertBearingX = 0;
+        metrics->vertBearingY = 0;
+
+        if ( hinting )
+          ft_glyphslot_grid_fit_metrics( cidglyph );
       }
     }
 
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index a83dbe3..a975aa4 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1707,15 +1707,6 @@
       FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 );
 
       FT_Outline_Get_CBox( &glyph->outline, &bbox );
-
-      if ( IS_HINTED( loader->load_flags ) )
-      {
-        /* grid-fit the bounding box */
-        bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
-        bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
-        bbox.xMax = FT_PIX_CEIL( bbox.xMax );
-        bbox.yMax = FT_PIX_CEIL( bbox.yMax );
-      }
     }
     else
       bbox = loader->bbox;
@@ -1744,10 +1735,6 @@
     glyph->metrics.horiBearingY = bbox.yMax;
     glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;
 
-    /* don't forget to hint the advance when we need to */
-    if ( IS_HINTED( loader->load_flags ) )
-      glyph->metrics.horiAdvance = FT_PIX_ROUND( glyph->metrics.horiAdvance );
-
     /* Now take care of vertical metrics.  In the case where there is    */
     /* no vertical information within the font (relatively common), make */
     /* up some metrics by `hand'...                                      */
@@ -1857,15 +1844,6 @@
       /*                                                               */
       left = ( bbox.xMin - bbox.xMax ) / 2;
 
-      /* grid-fit them if necessary */
-      if ( IS_HINTED( loader->load_flags ) )
-      {
-        left    = FT_PIX_FLOOR( left );
-        /* top should be floor'ed */
-        top     = FT_PIX_FLOOR( top );
-        advance = FT_PIX_ROUND( advance );
-      }
-
       glyph->metrics.vertBearingX = left;
       glyph->metrics.vertBearingY = top;
       glyph->metrics.vertAdvance  = advance;
@@ -1888,6 +1866,9 @@
     glyph->metrics.width  = bbox.xMax - bbox.xMin;
     glyph->metrics.height = bbox.yMax - bbox.yMin;
 
+    if ( IS_HINTED( loader->load_flags ) )
+      ft_glyphslot_grid_fit_metrics( glyph );
+
     return 0;
   }
 
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
index f45a83b..75d2e9b 100644
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -315,11 +315,7 @@
         glyph->root.linearHoriAdvance           = decoder.builder.advance.x;
         glyph->root.internal->glyph_transformed = 0;
 
-        /* make up vertical metrics */
-        metrics->vertBearingX = 0;
-        metrics->vertBearingY = 0;
-        metrics->vertAdvance  = 0;
-
+        metrics->vertAdvance          = 0;
         glyph->root.linearVertAdvance = 0;
 
         glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
@@ -363,42 +359,26 @@
               vec->y = FT_MulFix( vec->y, y_scale );
             }
 
-          FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
-
           /* Then scale the metrics */
           metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,  x_scale );
           metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  y_scale );
-
-          metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
-          metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
-
-          if ( hinting )
-          {
-            metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
-            metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
-
-            metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX );
-            metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY );
-          }
         }
 
         /* compute the other metrics */
         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
 
-        /* grid fit the bounding box if necessary */
-        if ( hinting )
-        {
-          cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
-          cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
-          cbox.xMax = FT_PIX_CEIL( cbox.xMax );
-          cbox.yMax = FT_PIX_CEIL( cbox.yMax );
-        }
-
         metrics->width  = cbox.xMax - cbox.xMin;
         metrics->height = cbox.yMax - cbox.yMin;
 
         metrics->horiBearingX = cbox.xMin;
         metrics->horiBearingY = cbox.yMax;
+
+        /* make up vertical ones */
+        metrics->vertBearingX = 0;
+        metrics->vertBearingY = 0;
+
+        if ( hinting )
+          ft_glyphslot_grid_fit_metrics( &glyph->root );
       }
 
       /* Set control data to the glyph charstrings.  Note that this is */