Commit 109fcf6086727f61f59a8ce9c569b85bb3d70ae8

David Turner 2000-05-17T23:35:37

fixed the sbit loader (src/base/sfnt/ttsbit.c) introduced a new load flag (FT_LOAD_CROP_BITMAP) used to indicate that we want embedded bitmaps to be cropped.. Thanks a lot to Yamano-uchi, Hidetoshi

diff --git a/CHANGES b/CHANGES
index 665c6a8..20c1c07 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
 LATEST_CHANGES
 
+  - fixed some bugs in the sbit loader (src/base/sfnt/ttsbit.c) + added
+    a new flag, FT_LOAD_CROP_BITMAP to query that bitmaps be cropped when
+    loaded from a file (maybe I should move the bitmap cropper to the
+    base layer ??).
+
   - changed the default number of gray levels of the smooth renderer to
     256 (instead of the previous 128). Of course, the human eye can't
 	see any difference ;-)
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 5a6fcab..164a4a0 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -1532,6 +1532,20 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
+  /*    FT_LOAD_CROP_BITMAP                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the font driver should try to crop the bitmap (i.e. remove all     */
+  /*    space around its black bits) when loading it. For now, this        */
+  /*    really only works with Embedded Bitmaps in TrueType fonts..        */
+  /*                                                                       */
+  /*                                                                       */
+#define FT_LOAD_CROP_BITMAP  64
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
   /*    FT_LOAD_PEDANTIC                                                   */
   /*                                                                       */
   /* <Description>                                                         */
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 9e6eb11..5775667 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -166,6 +166,7 @@
                                         TT_Int            x_ppem,
                                         TT_Int            y_ppem,
                                         TT_UInt           glyph_index,
+                                        TT_UInt           load_flags,
                                         FT_Stream         stream,
                                         FT_Bitmap*        map,
                                         TT_SBit_Metrics*  metrics );
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index 57cf6a5..7303af4 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -58,7 +58,7 @@
   /*                                                                       */
   static
   void  blit_sbit( FT_Bitmap*  target,
-                   char*       source,
+                   FT_Byte*    source,
                    FT_Int      line_bits,
                    FT_Bool     byte_padded,
                    FT_Int      x_offset,
@@ -115,19 +115,19 @@
             /* ensure that there are at least 8 bits in the accumulator */
             if ( loaded < 8 )
             {
-              acc    |= ((FT_UShort)*source++) << (8 - loaded);
+              acc    |= (FT_UShort)*source++ << (8 - loaded);
               loaded += 8;
             }
 
             /* now write one byte */
-            val     = (FT_Byte)(acc >> 8);
+            val = (FT_Byte)(acc >> 8);
             if (shift)
             {
               cur[0] |= val >> shift;
               cur[1] |= val << space;
             }
             else
-              cur[0] = val;
+              cur[0] |= val;
 
             cur++;
             acc   <<= 8;  /* remove bits from accumulator */
@@ -150,7 +150,7 @@
         /* ensure that there are at least `count' bits in the accumulator */
         if ( loaded < count )
         {
-          acc    |= ((FT_UShort)*source++) << (8 - loaded);
+          acc    |= (FT_UShort)*source++ << (8 - loaded);
           loaded += 8;
         }
 
@@ -464,6 +464,7 @@
     TT_ULong   num_strikes;
     TT_ULong   table_base;
 
+    face->num_sbit_strikes = 0;
 
     /* this table is optional */
     error = face->goto_table( face, TTAG_EBLC, stream, 0 );
@@ -724,7 +725,7 @@
                 else
                   *aglyph_offset = range->image_offset +
                                    n * range->image_size;
-                break;
+                goto Found;
               }
             }
           }
@@ -734,9 +735,9 @@
             goto Fail;
         }
 
+    Found:
         /* return successfully! */
         *arange  = range;
-
         return 0;
       }
     }
@@ -851,54 +852,55 @@
     TT_Error  error = TT_Err_Ok;
 
 
-    switch ( range->index_format )
+    switch ( range->image_format )
     {
-    case 1:  /* variable metrics */
-    case 3:
-    case 4:
-      {
-        switch ( range->image_format )
+    case 1:
+    case 2:
+    case 8:
+        /* variable small metrics */
         {
-        case 1:  /* small metrics */
-        case 2:
-        case 8:
-          {
-            TT_SBit_Small_Metrics  smetrics;
-
-
-            /* read small metrics */
-            if ( ACCESS_Frame( 5L ) )
-              goto Exit;
-            TT_Load_Small_SBit_Metrics( &smetrics, stream );
-            FORGET_Frame();
-
-            /* convert it to a big metrics */
-            metrics->height       = smetrics.height;
-            metrics->width        = smetrics.width;
-            metrics->horiBearingX = smetrics.bearingX;
-            metrics->horiBearingY = smetrics.bearingY;
-            metrics->horiAdvance  = smetrics.advance;
-
-            /* these metrics are made up at a higher level when */
-            /* needed.                                          */
-            metrics->vertBearingX = 0;
-            metrics->vertBearingY = 0;
-            metrics->vertAdvance  = 0;
-          }
-          break;
+          TT_SBit_Small_Metrics  smetrics;
 
-        default:  /* big metrics */
-          if ( ACCESS_Frame( 8L ) )
+          /* read small metrics */
+          if ( ACCESS_Frame( 5L ) )
             goto Exit;
-          TT_Load_SBit_Metrics( metrics, stream );
+          TT_Load_Small_SBit_Metrics( &smetrics, stream );
           FORGET_Frame();
+
+          /* convert it to a big metrics */
+          metrics->height       = smetrics.height;
+          metrics->width        = smetrics.width;
+          metrics->horiBearingX = smetrics.bearingX;
+          metrics->horiBearingY = smetrics.bearingY;
+          metrics->horiAdvance  = smetrics.advance;
+
+          /* these metrics are made up at a higher level when */
+          /* needed.                                          */
+          metrics->vertBearingX = 0;
+          metrics->vertBearingY = 0;
+          metrics->vertAdvance  = 0;
         }
+        break;
+
+    case 6:
+    case 7:
+    case 9:
+      /* variable big metrics */
+      {
+        if ( ACCESS_Frame( 8L ) )
+         goto Exit;
+        TT_Load_SBit_Metrics( metrics, stream );
+        FORGET_Frame();
       }
       break;
 
-    default:  /* constant metrics */
-      *metrics = range->metrics;
-    }
+    case 5:
+   default:  /* constant metrics */
+      if ( range->index_format == 2 || range->index_format == 5 )
+        *metrics = range->metrics;
+      else
+        return FT_Err_Invalid_File_Format;
+   }
 
   Exit:
     return error;
@@ -1177,7 +1179,7 @@
       /* don't forget to multiply `x_offset' by `map->pix_bits' as */
       /* the sbit blitter doesn't make a difference between pixmap */
       /* depths.                                                   */
-      blit_sbit( map, stream->cursor, line_bits, pad_bytes,
+      blit_sbit( map, (FT_Byte*)stream->cursor, line_bits, pad_bytes,
                  x_offset * pix_bits, y_offset );
 
       FORGET_Frame();
@@ -1267,6 +1269,9 @@
                                range->image_format, metrics, stream );
 
     case 8:  /* compound format */
+      FT_Skip_Stream( stream, 1L );
+      /* fallthrough */
+
     case 9:
       break;
 
@@ -1377,6 +1382,7 @@
                                 TT_Int            x_ppem,
                                 TT_Int            y_ppem,
                                 TT_UInt           glyph_index,
+                                TT_UInt           load_flags,
                                 FT_Stream         stream,
                                 FT_Bitmap*        map,
                                 TT_SBit_Metrics*  metrics )
@@ -1432,8 +1438,9 @@
       metrics->vertAdvance  =  advance * 12 / 10;
     }
 
-    /* Crop the bitmap now */
-    Crop_Bitmap( map, metrics );
+    /* Crop the bitmap now, unless specified otherwise */
+    if (load_flags & FT_LOAD_CROP_BITMAP)
+      Crop_Bitmap( map, metrics );
 
   Exit:
     return error;
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index 414ceae..944dc3e 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -93,6 +93,7 @@
                                 TT_Int            x_ppem,
                                 TT_Int            y_ppem,
                                 TT_UInt           glyph_index,
+                                TT_UInt           load_flags,
                                 FT_Stream         stream,
                                 FT_Bitmap*        map,
                                 TT_SBit_Metrics*  metrics );
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 9137758..33b4123 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -239,8 +239,30 @@
         root->charmaps[n] = (FT_CharMap)charmap;
       }
 
-      root->num_fixed_sizes = 0;
-      root->available_sizes = 0;
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+      if ( face->num_sbit_strikes )
+      {
+       face->root.num_fixed_sizes = face->num_sbit_strikes;
+       if ( ALLOC_ARRAY( face->root.available_sizes,
+                         face->num_sbit_strikes,
+                         FT_Bitmap_Size ) )
+         return error;
+
+       for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
+       {
+         face->root.available_sizes[n].width =
+           face->sbit_strikes[n].x_ppem;
+         face->root.available_sizes[n].height =
+           face->sbit_strikes[n].y_ppem;
+       }
+      }
+      else
+#else
+      {
+       root->num_fixed_sizes = 0;
+       root->available_sizes = 0;
+      }
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
       /*****************************************************************/
       /*                                                               */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index c388a6c..f7be829 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1231,6 +1231,7 @@
                                      size->root.metrics.x_ppem,
                                      size->root.metrics.y_ppem,
                                      glyph_index,
+                                     load_flags,
                                      stream,
                                      &glyph->bitmap,
                                      &metrics );
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index 089227a..faccdc3 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -373,6 +373,11 @@
     FREE( face->root.family_name );
     FREE( face->root.style_name );
 
+    /* freeing sbit size table */
+    face->root.num_fixed_sizes = 0;
+    if ( face->root.available_sizes )
+      FREE( face->root.available_sizes );
+
     face->sfnt = 0;
   }