Commit 3f539694f1c1d6fd14df1a4516c345873f446e77

David Turner 2007-03-28T14:53:40

fixing bug in the padding zero-ing of the bitmap emboldener

diff --git a/ChangeLog b/ChangeLog
index d508f39..25add77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-03-28  David Turner  <david@freetype.org>
+
+	* src/base/ftbitmap.c (ft_bitmap_assure_buffer): fix zero-ing of the
+	padding.
+
 2007-03-28  Werner Lemberg  <wl@gnu.org>
 
 	* src/bdf/bdflib.c (setsbit, sbitset): Handle values >= 128
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 50c9382..4d5b85b 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -103,75 +103,78 @@
     FT_Error        error;
     int             pitch;
     int             new_pitch;
-    FT_UInt         ppb;
-    FT_Int          i, width;
+    FT_UInt         bpp;
+    FT_Int          i, width, height;
     unsigned char*  buffer;
 
 
-    width = bitmap->width;
-    pitch = bitmap->pitch;
+    width  = bitmap->width;
+    height = bitmap->rows;
+    pitch  = bitmap->pitch;
     if ( pitch < 0 )
       pitch = -pitch;
 
     switch ( bitmap->pixel_mode )
     {
     case FT_PIXEL_MODE_MONO:
-      ppb = 8;
+      bpp       = 1;
+      new_pitch = ( width + xpixels + 7 ) >> 3;
       break;
     case FT_PIXEL_MODE_GRAY2:
-      ppb = 4;
+      bpp       = 2;
+      new_pitch = ( width + xpixels + 3 ) >> 2;
       break;
     case FT_PIXEL_MODE_GRAY4:
-      ppb = 2;
+      bpp       = 4;
+      new_pitch = ( width + xpixels + 1 ) >> 1;
       break;
     case FT_PIXEL_MODE_GRAY:
     case FT_PIXEL_MODE_LCD:
     case FT_PIXEL_MODE_LCD_V:
-      ppb = 1;
+      bpp       = 8;
+      new_pitch = ( width + xpixels );
       break;
     default:
       return FT_Err_Invalid_Glyph_Format;
     }
 
     /* if no need to allocate memory */
-    if ( ypixels == 0 && pitch * ppb >= bitmap->width + xpixels )
+    if ( ypixels == 0 && new_pitch <= pitch )
     {
       /* zero the padding */
-      for ( i = 0; i < bitmap->rows; i++ )
-      {
-        unsigned char*  last_byte;
-        int             bits = xpixels * ( 8 / ppb );
-        int             mask = 0;
-
+      FT_Int   bit_width =  pitch*8;
+      FT_Int   bit_last  =  (width + xpixels)*bpp;
 
-        last_byte = bitmap->buffer + i * pitch + ( bitmap->width - 1 ) / ppb;
-
-        if ( bits >= 8 )
-        {
-          FT_MEM_ZERO( last_byte + 1, bits / 8 );
-          bits %= 8;
-        }
+      if ( bit_last < bit_width )
+      {
+        FT_Byte*  line  = bitmap->buffer + (bit_last >> 3);
+        FT_Int    shift = (bit_last & 7);
+        FT_UInt   mask  = 0xFF00U >> shift;
+        FT_Int    count = height;
 
-        if ( bits > 0 )
+        for ( ; count > 0; count--, line += pitch )
         {
-          while ( bits-- > 0 )
-            mask |= 1 << bits;
+          FT_Byte*  write = line;
+          FT_Byte*  end   = line + pitch;
 
-          *last_byte &= ~mask;
+          if ( shift > 0 )
+          {
+            write[0] = (FT_Byte)(write[0] & mask);
+            write++;
+          }
+          if (write < end)
+            FT_MEM_ZERO( write, end-write );
         }
       }
-
       return FT_Err_Ok;
     }
 
-    new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
-
     if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
       return error;
 
     if ( bitmap->pitch > 0 )
     {
-      FT_Int  len = ( width + ppb - 1 ) / ppb;
+      FT_Int  len = (width*bpp + 7) >> 3;
 
 
       for ( i = 0; i < bitmap->rows; i++ )
@@ -180,7 +183,7 @@
     }
     else
     {
-      FT_Int  len = ( width + ppb - 1 ) / ppb;
+      FT_Int  len = (width*bpp + 7) >> 3;
 
 
       for ( i = 0; i < bitmap->rows; i++ )
@@ -194,7 +197,7 @@
     if ( bitmap->pitch < 0 )
       new_pitch = -new_pitch;
 
-    /* set pitch only */
+    /* set pitch only, width and height are left untouched */
     bitmap->pitch = new_pitch;
 
     return FT_Err_Ok;
@@ -244,8 +247,8 @@
           align = ( bitmap->width + xstr + 1 ) / 2;
 
         FT_Bitmap_New( &tmp );
-        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
 
+        error = FT_Bitmap_Convert( library, bitmap, &tmp, align );
         if ( error )
           return error;