Commit 942aa5fff46abad9216d2943f1ffaf9e83e32c29

Chris Liddell 2015-01-18T07:29:48

[raster] Fix Savannah bug #44022. Add fallback for glyphs with degenerate bounding boxes. If a glyph has only one very narrow feature, the bbox can end up with either the width or height of the bbox being 0, in which case no raster memory is allocated and no attempt is made to render the glyph. This is less than ideal when the drop-out compensation in the rendering code would actually result in the glyph being rendered. This problem can be observed with the `I' glyph (gid 47) in the Autodesk RomanS TrueType font. * src/raster/ftrend1.c (ft_raster1_render): Add a fallback if either dimension is zero to explicitly round up/down (instead of simply round).

diff --git a/ChangeLog b/ChangeLog
index 84eee06..268e4b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2015-01-18  Chris Liddell  <chris.liddell@artifex.com>
+
+	[raster] Fix Savannah bug #44022.
+
+	Add fallback for glyphs with degenerate bounding boxes.
+
+	If a glyph has only one very narrow feature, the bbox can end up
+	with either the width or height of the bbox being 0, in which case
+	no raster memory is allocated and no attempt is made to render the
+	glyph.  This is less than ideal when the drop-out compensation in
+	the rendering code would actually result in the glyph being
+	rendered.
+
+	This problem can be observed with the `I' glyph (gid 47) in the
+	Autodesk RomanS TrueType font.
+
+	* src/raster/ftrend1.c (ft_raster1_render): Add a fallback if either
+	dimension is zero to explicitly round up/down (instead of simply
+	round).
+
 2015-01-17  Werner Lemberg  <wl@gnu.org>
 
 	Add some tools to handle yearly copyright notice updates.
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index 437996b..dc03b34 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -104,7 +104,7 @@
   {
     FT_Error     error;
     FT_Outline*  outline;
-    FT_BBox      cbox;
+    FT_BBox      cbox, cbox0;
     FT_UInt      width, height, pitch;
     FT_Bitmap*   bitmap;
     FT_Memory    memory;
@@ -133,14 +133,14 @@
       FT_Outline_Translate( outline, origin->x, origin->y );
 
     /* compute the control box, and grid fit it */
-    FT_Outline_Get_CBox( outline, &cbox );
+    FT_Outline_Get_CBox( outline, &cbox0 );
 
     /* undocumented but confirmed: bbox values get rounded */
 #if 1
-    cbox.xMin = FT_PIX_ROUND( cbox.xMin );
-    cbox.yMin = FT_PIX_ROUND( cbox.yMin );
-    cbox.xMax = FT_PIX_ROUND( cbox.xMax );
-    cbox.yMax = FT_PIX_ROUND( cbox.yMax );
+    cbox.xMin = FT_PIX_ROUND( cbox0.xMin );
+    cbox.yMin = FT_PIX_ROUND( cbox0.yMin );
+    cbox.xMax = FT_PIX_ROUND( cbox0.xMax );
+    cbox.yMax = FT_PIX_ROUND( cbox0.yMax );
 #else
     cbox.xMin = FT_PIX_FLOOR( cbox.xMin );
     cbox.yMin = FT_PIX_FLOOR( cbox.yMin );
@@ -148,8 +148,28 @@
     cbox.yMax = FT_PIX_CEIL( cbox.yMax );
 #endif
 
+    /* If either `width' or `height' round to 0, try    */
+    /* explicitly rounding up/down.  In the case of     */
+    /* glyphs containing only one very narrow feature,  */
+    /* this gives the drop-out compensation in the scan */
+    /* conversion code a chance to do its stuff.        */
     width  = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
+    if ( width == 0 )
+    {
+      cbox.xMin = FT_PIX_FLOOR( cbox0.xMin );
+      cbox.xMax = FT_PIX_CEIL( cbox0.xMax );
+
+      width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 );
+    }
+
     height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
+    if ( height == 0 )
+    {
+      cbox.yMin = FT_PIX_FLOOR( cbox0.yMin );
+      cbox.yMax = FT_PIX_CEIL( cbox0.yMax );
+
+      height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 );
+    }
 
     if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX )
     {