shithub: freetype+ttf2subf

Download patch

ref: 0489328e974a1f25cd2f8e3dd180468b6bd7be99
parent: cae232d4f40552ab12960dc62610f7f08954365b
author: David Turner <[email protected]>
date: Wed Feb 6 06:22:56 EST 2002

fixing memory leak in the PCF driver, and managing the
"AVERAGE_WIDTH" property in PCF fonts to return correct
character pixel (width/height) pairs for embedded bitmaps..

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2002-02-06  David Turner   <[email protected]>
+
+        * src/sfnt/ttcmap.c: removing compiler warnings
+
+        * src/pcf/pcfread.c, src/pcf/pcf.h, src/pcf/pcfdriver.c:
+        removing minor bugs (delaying format checks out of
+        FT_Access_Frame .. FT_Forget_Frame blocks to avoid leaving the
+        stream in an incorrect state when encountering an invalid PCF
+        font)
+        
+        reformatting / renaming a few functions for the sake of consistency
+
+
+2002-02-06  Detlef W�rkner
+
+        * src/pcf/pcfdriver.c (FT_Done_Face): fixed small memory leak
+        
+        * src/pcf/pcfread.c (pcf_load_font): now handles the "AVERAGE_WIDTH"
+        property to return correct character pixel (width/height) pairs for
+        embedded bitmaps..
+
+
 2002-02-04  Keith Packard  <[email protected]>
 
 	Adding the function `FT_Get_Next_Char', doing the obvious thing
--- a/src/pcf/pcf.h
+++ b/src/pcf/pcf.h
@@ -159,11 +159,6 @@
   } PCF_FaceRec, *PCF_Face;
 
 
-  /* XXX hack */
-  FT_LOCAL FT_Error
-  PCF_Done_Face( PCF_Face  face );
-
-
   /* macros for pcf font format */
 
 #define LSBFirst  0
--- a/src/pcf/pcfdriver.c
+++ b/src/pcf/pcfdriver.c
@@ -48,24 +48,32 @@
 #define FT_COMPONENT  trace_pcfdriver
 
 
-  FT_LOCAL_DEF FT_Error
-  PCF_Done_Face( PCF_Face  face )
+  static FT_Error
+  PCF_Face_Done( PCF_Face  face )
   {
     FT_Memory    memory = FT_FACE_MEMORY( face );
-    PCF_Property tmp    = face->properties;
-    int i;
 
 
     FREE( face->encodings );
     FREE( face->metrics );
 
-    for ( i = 0; i < face->nprops; i++ )
+    /* free properties */
     {
-      FREE( tmp->name );
-      if ( tmp->isString )
-        FREE( tmp->value );
+      PCF_Property prop = face->properties;
+      FT_Int       i;
+      
+      for ( i = 0; i < face->nprops; i++ )
+      {
+        prop = &face->properties[i];
+        
+        FREE( prop->name );
+        if ( prop->isString )
+          FREE( prop->value );
+      }
+      
+      FREE( face->properties );
     }
-    FREE( face->properties );
+    
     FREE( face->toc.tables );
     FREE( face->root.family_name );
     FREE( face->root.available_sizes );
@@ -79,7 +87,7 @@
 
 
   static FT_Error
-  PCF_Init_Face( FT_Stream      stream,
+  PCF_Face_Init( FT_Stream      stream,
                  PCF_Face       face,
                  FT_Int         face_index,
                  FT_Int         num_params,
@@ -100,7 +108,7 @@
 
   Fail:
     FT_TRACE2(( "[not a valid PCF file]\n" ));
-    PCF_Done_Face( face );
+    PCF_Face_Done( face );
 
     return PCF_Err_Unknown_File_Format; /* error */
   }
@@ -138,12 +146,13 @@
 
 
   static FT_Error
-  PCF_Load_Glyph( FT_GlyphSlot  slot,
+  PCF_Glyph_Load( FT_GlyphSlot  slot,
                   FT_Size       size,
                   FT_UInt       glyph_index,
                   FT_Int        load_flags )
   {
     PCF_Face    face   = (PCF_Face)FT_SIZE_FACE( size );
+    FT_Stream   stream = face->root.stream;
     FT_Error    error  = PCF_Err_Ok;
     FT_Memory   memory = FT_FACE(face)->memory;
     FT_Bitmap*  bitmap = &slot->bitmap;
@@ -150,7 +159,6 @@
     PCF_Metric  metric;
     int         bytes;
 
-    FT_Stream   stream = face->root.stream;
 
     FT_UNUSED( load_flags );
 
@@ -249,7 +257,7 @@
 
 
   static FT_UInt
-  PCF_Get_Char_Index( FT_CharMap  charmap,
+  PCF_Char_Get_Index( FT_CharMap  charmap,
                       FT_Long     char_code )
   {
     PCF_Face      face     = (PCF_Face)charmap->face;
@@ -277,7 +285,7 @@
 
 
   static FT_Long
-  PCF_Get_Next_Char( FT_CharMap  charmap,
+  PCF_Char_Get_Next( FT_CharMap  charmap,
                      FT_Long     char_code )
   {
     PCF_Face      face     = (PCF_Face)charmap->face;
@@ -285,7 +293,7 @@
     int           low, high, mid;
 
 
-    FT_TRACE4(( "get_char_index %ld\n", char_code ));
+    FT_TRACE4(( "get_next_char %ld\n", char_code ));
     
     char_code++;
     low  = 0;
@@ -338,8 +346,8 @@
     sizeof( FT_SizeRec ),
     sizeof( FT_GlyphSlotRec ),
 
-    (FTDriver_initFace)     PCF_Init_Face,
-    (FTDriver_doneFace)     PCF_Done_Face,
+    (FTDriver_initFace)     PCF_Face_Init,
+    (FTDriver_doneFace)     PCF_Face_Done,
     (FTDriver_initSize)     0,
     (FTDriver_doneSize)     0,
     (FTDriver_initGlyphSlot)0,
@@ -348,14 +356,14 @@
     (FTDriver_setCharSizes) PCF_Set_Pixel_Size,
     (FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
 
-    (FTDriver_loadGlyph)    PCF_Load_Glyph,
-    (FTDriver_getCharIndex) PCF_Get_Char_Index,
+    (FTDriver_loadGlyph)    PCF_Glyph_Load,
+    (FTDriver_getCharIndex) PCF_Char_Get_Index,
 
     (FTDriver_getKerning)   0,
     (FTDriver_attachFile)   0,
     (FTDriver_getAdvances)  0,
 
-    (FTDriver_getNextChar)  PCF_Get_Next_Char
+    (FTDriver_getNextChar)  PCF_Char_Get_Next,
   };
 
 
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -94,8 +94,8 @@
     PCF_Toc    toc = &face->toc;
     PCF_Table  tables;
 
-    FT_Memory     memory = FT_FACE(face)->memory;
-    unsigned int  n;
+    FT_Memory  memory = FT_FACE(face)->memory;
+    FT_UInt    n;
 
 
     if ( FILE_Seek ( 0 )                   ||
@@ -119,8 +119,8 @@
 #if defined( FT_DEBUG_LEVEL_TRACE )
 
     {
-      unsigned int  i, j;
-      const char    *name = "?";
+      FT_UInt      i, j;
+      const char*  name = "?";
 
 
       FT_TRACE4(( "Tables count: %ld\n", face->toc.count ));
@@ -128,8 +128,9 @@
       for ( i = 0; i < toc->count; i++ )
       {
         for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
-          if ( tables[i].type == (unsigned int)( 1 << j ) )
+          if ( tables[i].type == (FT_UInt)( 1 << j ) )
             name = tableNames[j];
+            
         FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX "
                     "size=0x%06lX (%8ld) offset=0x%04lX\n",
                     i, name,
@@ -199,80 +200,60 @@
   };
 
 
-  static FT_Error
-  pcf_parse_metric( FT_Stream              stream,
-                    const FT_Frame_Field*  header,
-                    PCF_Metric             metric )
-  {
-    FT_Error  error = PCF_Err_Ok;
 
 
-    if ( READ_Fields( header, metric ) )
-      return error;
-
-    return PCF_Err_Ok;
-  }
-
-
   static FT_Error
-  pcf_parse_compressed_metric( FT_Stream   stream,
-                               PCF_Metric  metric )
-  {
-    PCF_Compressed_MetricRec  compr_metric;
-    FT_Error                  error = PCF_Err_Ok;
-
-
-    if ( READ_Fields( pcf_compressed_metric_header, &compr_metric ) )
-      return error;
-
-    metric->leftSideBearing =
-      (FT_Short)( compr_metric.leftSideBearing - 0x80 );
-    metric->rightSideBearing =
-      (FT_Short)( compr_metric.rightSideBearing - 0x80 );
-    metric->characterWidth =
-      (FT_Short)( compr_metric.characterWidth - 0x80 );
-    metric->ascent =
-      (FT_Short)( compr_metric.ascent - 0x80 );
-    metric->descent =
-      (FT_Short)( compr_metric.descent - 0x80 );
-    metric->attributes = 0;
-
-    return PCF_Err_Ok;
-  }
-
-
-  static FT_Error
   pcf_get_metric( FT_Stream   stream,
                   FT_ULong    format,
                   PCF_Metric  metric )
   {
-    FT_Error error = PCF_Err_Ok;
+    FT_Error               error = PCF_Err_Ok;
 
 
     if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
     {
-      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-        error = pcf_parse_metric( stream, pcf_metric_msb_header, metric );
-      else
-        error = pcf_parse_metric( stream, pcf_metric_header, metric );
+      const FT_Frame_Field*   fields; 
+  
+      /* parsing normal metrics */
+      fields = PCF_BYTE_ORDER( format ) == MSBFirst
+             ? pcf_metric_msb_header
+             : pcf_metric_header;
+
+      /* the following sets 'error' but doesn't return in case of failure */             
+      (void) READ_Fields( fields, metric );
     }
     else
-      error = pcf_parse_compressed_metric( stream, metric );
+    {
+      PCF_Compressed_MetricRec  compr;
 
+
+      /* parsing compressed metrics */
+      if ( READ_Fields( pcf_compressed_metric_header, &compr ) )
+        goto Exit;
+
+      metric->leftSideBearing  = (FT_Short)( compr.leftSideBearing  - 0x80 );
+      metric->rightSideBearing = (FT_Short)( compr.rightSideBearing - 0x80 );
+      metric->characterWidth   = (FT_Short)( compr.characterWidth   - 0x80 );
+      metric->ascent           = (FT_Short)( compr.ascent           - 0x80 );
+      metric->descent          = (FT_Short)( compr.descent          - 0x80 );
+      metric->attributes       = 0;
+    }
+
+  Exit:
     return error;
   }
 
 
   static FT_Error
-  pcfSeekToType( FT_Stream  stream,
-                 PCF_Table  tables,
-                 int        ntables,
-                 FT_ULong   type,
-                 FT_ULong*  formatp,
-                 FT_ULong*  sizep )
+  pcf_seek_to_table_type( FT_Stream  stream,
+                          PCF_Table  tables,
+                          FT_Int     ntables,
+                          FT_ULong   type,
+                          FT_ULong  *aformat,
+                          FT_ULong  *asize )
   {
     FT_Error error;
-    int      i;
+    FT_Int   i;
 
 
     for ( i = 0; i < ntables; i++ )
@@ -280,10 +261,13 @@
       {
         if ( stream->pos > tables[i].offset )
           return PCF_Err_Invalid_Stream_Skip;
+
         if ( FILE_Skip( tables[i].offset - stream->pos ) )
           return PCF_Err_Invalid_Stream_Skip;
-        *sizep   = tables[i].size;  /* unused - to be removed */
-        *formatp = tables[i].format;
+
+        *asize   = tables[i].size;  /* unused - to be removed */
+        *aformat = tables[i].format;
+        
         return PCF_Err_Ok;
       }
 
@@ -292,11 +276,11 @@
 
 
   static FT_Bool
-  pcfHasType( PCF_Table  tables,
-              int        ntables,
-              FT_ULong   type )
+  pcf_has_table_type( PCF_Table  tables,
+                      FT_Int     ntables,
+                      FT_ULong   type )
   {
-    int i;
+    FT_Int  i;
 
 
     for ( i = 0; i < ntables; i++ )
@@ -336,8 +320,8 @@
 
 
   static PCF_Property
-  find_property( PCF_Face          face,
-                 const FT_String*  prop )
+  pcf_find_property( PCF_Face          face,
+                     const FT_String*  prop )
   {
     PCF_Property  properties = face->properties;
     FT_Bool       found      = 0;
@@ -363,7 +347,7 @@
   {
     PCF_ParseProperty  props      = 0;
     PCF_Property       properties = 0;
-    int                nprops, i;
+    FT_Int             nprops, i;
     FT_ULong           format, size;
     FT_Error           error;
     FT_Memory          memory     = FT_FACE(face)->memory;
@@ -371,12 +355,12 @@
     FT_String*         strings    = 0;
 
 
-    error = pcfSeekToType( stream,
-                           face->toc.tables,
-                           face->toc.count,
-                           PCF_PROPERTIES,
-                           &format,
-                           &size );
+    error = pcf_seek_to_table_type( stream,
+                                    face->toc.tables,
+                                    face->toc.count,
+                                    PCF_PROPERTIES,
+                                    &format,
+                                    &size );
     if ( error )
       goto Bail;
 
@@ -496,7 +480,7 @@
     int         nmetrics = -1;
 
 
-    error = pcfSeekToType( stream,
+    error = pcf_seek_to_table_type( stream,
                            face->toc.tables,
                            face->toc.count,
                            PCF_METRICS,
@@ -573,12 +557,12 @@
     char*      bitmaps;
 
 
-    error = pcfSeekToType( stream,
-                           face->toc.tables,
-                           face->toc.count,
-                           PCF_BITMAPS,
-                           &format,
-                           &size );
+    error = pcf_seek_to_table_type( stream,
+                                    face->toc.tables,
+                                    face->toc.count,
+                                    PCF_BITMAPS,
+                                    &format,
+                                    &size );
     if ( error )
       return error;
 
@@ -585,15 +569,18 @@
     error = FT_Access_Frame( stream, 8 );
     if ( error )
       return error;
-    format = GET_ULongLE();
-    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
-      return PCF_Err_Invalid_File_Format;
 
+    format = GET_ULongLE();
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
       nbitmaps  = GET_ULong();
     else
       nbitmaps  = GET_ULongLE();
+
     FT_Forget_Frame( stream );
+
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+      return PCF_Err_Invalid_File_Format;
+
     if ( nbitmaps != face->nmetrics )
       return PCF_Err_Invalid_File_Format;
 
@@ -600,8 +587,6 @@
     if ( ALLOC( offsets, nbitmaps * sizeof ( FT_ULong ) ) )
       return error;
 
-    if ( error )
-      goto Bail;
     for ( i = 0; i < nbitmaps; i++ )
     {
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
@@ -614,8 +599,6 @@
     if ( error )
       goto Bail;
 
-    if ( error )
-      goto Bail;
     for ( i = 0; i < GLYPHPADOPTIONS; i++ )
     {
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
@@ -664,7 +647,7 @@
     PCF_Encoding  tmpEncoding, encoding = 0;
 
 
-    error = pcfSeekToType( stream,
+    error = pcf_seek_to_table_type( stream,
                            face->toc.tables,
                            face->toc.count,
                            PCF_BDF_ENCODINGS,
@@ -676,9 +659,8 @@
     error = FT_Access_Frame( stream, 14 );
     if ( error )
       return error;
+
     format = GET_ULongLE();
-    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
-      return PCF_Err_Invalid_File_Format;
 
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
     {
@@ -699,6 +681,9 @@
 
     FT_Forget_Frame( stream );
 
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+      return PCF_Err_Invalid_File_Format;
+
     FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
                 firstCol, lastCol, firstRow, lastRow ));
 
@@ -810,16 +795,17 @@
     PCF_Accel  accel = &face->accel;
 
 
-    error = pcfSeekToType( stream,
-                           face->toc.tables,
-                           face->toc.count,
-                           type,
-                           &format,
-                           &size );
+    error = pcf_seek_to_table_type( stream,
+                                    face->toc.tables,
+                                    face->toc.count,
+                                    type,
+                                    &format,
+                                    &size );
     if ( error )
       goto Bail;
 
     error = READ_ULongLE( format );
+
     if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )  &&
          !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
       goto Bail;
@@ -838,6 +824,7 @@
     error = pcf_get_metric( stream, format, &(accel->minbounds) );
     if ( error )
       goto Bail;
+
     error = pcf_get_metric( stream, format, &(accel->maxbounds) );
     if ( error )
       goto Bail;
@@ -847,6 +834,7 @@
       error = pcf_get_metric( stream, format, &(accel->ink_minbounds) );
       if ( error )
         goto Bail;
+
       error = pcf_get_metric( stream, format, &(accel->ink_maxbounds) );
       if ( error )
         goto Bail;
@@ -881,7 +869,7 @@
       return error;;
 
     /* Use the old accelerators if no BDF accelerators are in the file. */
-    hasBDFAccelerators = pcfHasType( face->toc.tables,
+    hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
                                      face->toc.count,
                                      PCF_BDF_ACCELERATORS );
     if ( !hasBDFAccelerators )
@@ -933,7 +921,7 @@
         root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
       root->style_flags = 0;
-      prop = find_property( face, "SLANT" );
+      prop = pcf_find_property( face, "SLANT" );
       if ( prop != NULL )
         if ( prop->isString )
           if ( ( *(prop->value.atom) == 'O' ) ||
@@ -940,7 +928,7 @@
                ( *(prop->value.atom) == 'I' ) )
             root->style_flags |= FT_STYLE_FLAG_ITALIC;
 
-      prop = find_property( face, "WEIGHT_NAME" );
+      prop = pcf_find_property( face, "WEIGHT_NAME" );
       if ( prop != NULL )
         if ( prop->isString )
           if ( *(prop->value.atom) == 'B' )
@@ -957,7 +945,7 @@
       else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
         root->style_name = (char *)"Italic";
 
-      prop = find_property( face, "FAMILY_NAME" );
+      prop = pcf_find_property( face, "FAMILY_NAME" );
       if ( prop != NULL )
       {
         if ( prop->isString )
@@ -979,33 +967,43 @@
       if ( ALLOC_ARRAY( root->available_sizes, 1, FT_Bitmap_Size ) )
         goto Bail;
 
-      prop = find_property( face, "PIXEL_SIZE" );
+      prop = pcf_find_property( face, "PIXEL_SIZE" );
       if ( prop != NULL )
       {
+        root->available_sizes->height = 
         root->available_sizes->width  = (FT_Short)( prop->value.integer );
-        root->available_sizes->height = (FT_Short)( prop->value.integer );
         
+        prop = pcf_find_property( face, "AVERAGE_WIDTH" );
+        if ( prop != NULL )
+          root->available_sizes->width = (FT_Short)( prop->value.integer / 10 );
+        
         size_set = 1;
       }
       else 
       {
-        prop = find_property( face, "POINT_SIZE" );
+        prop = pcf_find_property( face, "POINT_SIZE" );
         if ( prop != NULL )
         {
-          PCF_Property  xres = 0, yres = 0;
+          PCF_Property  xres, yres, avgw;
 
 
-          xres = find_property( face, "RESOLUTION_X" );
-          yres = find_property( face, "RESOLUTION_Y" );
-              
-          if ( ( xres != NULL ) && ( yres != NULL ) )
+          xres = pcf_find_property( face, "RESOLUTION_X" );
+          yres = pcf_find_property( face, "RESOLUTION_Y" );
+          avgw = pcf_find_property( face, "AVERAGE_WIDTH" );
+
+          if ( ( yres != NULL ) && ( ( xres != NULL ) || ( avgw == NULL ) ) )
           {
-            root->available_sizes->width =
-              (FT_Short)( prop->value.integer *  
-                          xres->value.integer / 720 );
             root->available_sizes->height =
               (FT_Short)( prop->value.integer *  
                           yres->value.integer / 720 ); 
+
+            if ( avgw != NULL )
+              root->available_sizes->width =
+                (FT_Short)( avgw->value.integer / 10 );
+            else
+              root->available_sizes->width =
+                (FT_Short)( prop->value.integer *  
+                            xres->value.integer / 720 );
                   
             size_set = 1;
           }
@@ -1033,8 +1031,8 @@
         PCF_Property  charset_registry = 0, charset_encoding = 0;
 
 
-        charset_registry = find_property( face, "CHARSET_REGISTRY" );
-        charset_encoding = find_property( face, "CHARSET_ENCODING" );
+        charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
+        charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );
 
         if ( ( charset_registry != NULL ) &&
              ( charset_encoding != NULL ) )
@@ -1072,7 +1070,6 @@
     return PCF_Err_Ok;
 
   Bail:
-    PCF_Done_Face( face );
     return PCF_Err_Invalid_File_Format;
   }