freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 8b75544 2/2: [pcf] Revise driver.


From: Werner LEMBERG
Subject: [freetype2] master 8b75544 2/2: [pcf] Revise driver.
Date: Fri, 6 Jan 2017 10:48:19 +0000 (UTC)

branch: master
commit 8b755445bb36041de6dfd9596891a4134f3f3d39
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [pcf] Revise driver.
    
    This commit improves tracing and handling of malformed fonts.  In
    particular, the changes to `pcf_get_properties' fix
    
      https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=379
    
    * src/pcf/pcfread.c (tableNames): Use long names for better
    readability.
    (pcf_read_TOC): Allow at most 9 tables.
    (pcf_get_properties): Allow at most 256 properties.
    Limit strings array length to 256 * (65536 + 1) bytes.
    Better tracing.
    (pcf_get_metric): Trace metric data.
    (pcf_get_metrics): Allow at most 65536 metrics.
    Fix comparison of `metrics->ascent' and `metrics->descent' to avoid
    potential overflow.
    Better tracing.
    (pcf_get_bitmaps): Allow at most 65536 bitmaps.
    Better tracing.
    (pcf_get_encodings, pcf_get_accel): Better tracing.
    
    * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Don't trace `format' details.
    These are now shown by `pcf_get_bitmaps'.
---
 ChangeLog          |   27 ++++++
 src/pcf/pcfdrivr.c |   25 +++--
 src/pcf/pcfread.c  |  272 +++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 236 insertions(+), 88 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e7571ac..a3e33e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2017-01-06  Werner Lemberg  <address@hidden>
+
+       [pcf] Revise driver.
+
+       This commit improves tracing and handling of malformed fonts.  In
+       particular, the changes to `pcf_get_properties' fix
+
+         https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=379
+
+       * src/pcf/pcfread.c (tableNames): Use long names for better
+       readability.
+       (pcf_read_TOC): Allow at most 9 tables.
+       (pcf_get_properties): Allow at most 256 properties.
+       Limit strings array length to 256 * (65536 + 1) bytes.
+       Better tracing.
+       (pcf_get_metric): Trace metric data.
+       (pcf_get_metrics): Allow at most 65536 metrics.
+       Fix comparison of `metrics->ascent' and `metrics->descent' to avoid
+       potential overflow.
+       Better tracing.
+       (pcf_get_bitmaps): Allow at most 65536 bitmaps.
+       Better tracing.
+       (pcf_get_encodings, pcf_get_accel): Better tracing.
+
+       * src/pcf/pcfdrivr.c (PCF_Glyph_Load): Don't trace `format' details.
+       These are now shown by `pcf_get_bitmaps'.
+
 2017-01-04  Werner Lemberg  <address@hidden>
 
        * src/pcf/pcfdrivr.c (PCF_Face_Init): Trace compression format.
diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c
index 39cef4d..10d5c20 100644
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -524,11 +524,6 @@ THE SOFTWARE.
     bitmap->num_grays  = 1;
     bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
 
-    FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
-                  PCF_BIT_ORDER( face->bitmapsFormat ),
-                  PCF_BYTE_ORDER( face->bitmapsFormat ),
-                  PCF_GLYPH_PAD( face->bitmapsFormat ) ));
-
     switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
     {
     case 1:
@@ -630,19 +625,23 @@ THE SOFTWARE.
       }
       else
       {
-        if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL 
) )
+        if ( prop->value.l > 0x7FFFFFFFL          ||
+             prop->value.l < ( -1 - 0x7FFFFFFFL ) )
         {
-          FT_TRACE1(( "pcf_get_bdf_property: " ));
-          FT_TRACE1(( "too large integer 0x%x is truncated\n" ));
+          FT_TRACE1(( "pcf_get_bdf_property:" ));
+          FT_TRACE1(( " too large integer 0x%x is truncated\n" ));
         }
-        /* Apparently, the PCF driver loads all properties as signed integers!
-         * This really doesn't seem to be a problem, because this is
-         * sufficient for any meaningful values.
+
+        /*
+         *  The PCF driver loads all properties as signed integers.
+         *  This really doesn't seem to be a problem, because this is
+         *  sufficient for any meaningful values.
          */
         aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;
         aproperty->u.integer = (FT_Int32)prop->value.l;
       }
-      return 0;
+
+      return FT_Err_Ok;
     }
 
     return FT_THROW( Invalid_Argument );
@@ -657,7 +656,7 @@ THE SOFTWARE.
     *acharset_encoding = face->charset_encoding;
     *acharset_registry = face->charset_registry;
 
-    return 0;
+    return FT_Err_Ok;
   }
 
 
diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c
index 95ee570..38ba110 100644
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -50,8 +50,15 @@ THE SOFTWARE.
 #ifdef FT_DEBUG_LEVEL_TRACE
   static const char* const  tableNames[] =
   {
-    "prop", "accl", "mtrcs", "bmps", "imtrcs",
-    "enc", "swidth", "names", "accel"
+    "properties",
+    "accelerators",
+    "metrics",
+    "bitmaps",
+    "ink metrics",
+    "encodings",
+    "swidths",
+    "glyph names",
+    "BDF accelerators"
   };
 #endif
 
@@ -109,22 +116,20 @@ THE SOFTWARE.
     if ( stream->size < 16 )
       return FT_THROW( Invalid_File_Format );
 
-    /* We need 16 bytes per TOC entry.  Additionally, as a */
-    /* heuristic protection against gzip bombs (i.e., very */
-    /* small input files that expand to insanely large     */
-    /* files), we limit the number of TOC entries to 1024. */
-    if ( toc->count > stream->size >> 4 ||
-         toc->count > 1024              )
+    /* we need 16 bytes per TOC entry, */
+    /* and there can be most 9 tables  */
+    if ( toc->count > ( stream->size >> 4 ) ||
+         toc->count > 9                     )
     {
       FT_TRACE0(( "pcf_read_TOC: adjusting number of tables"
                   " (from %d to %d)\n",
                   toc->count,
-                  FT_MIN( stream->size >> 4, 1024 ) ));
-      toc->count = FT_MIN( stream->size >> 4, 1024 );
+                  FT_MIN( stream->size >> 4, 9 ) ));
+      toc->count = FT_MIN( stream->size >> 4, 9 );
     }
 
     if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) )
-      return FT_THROW( Out_Of_Memory );
+      return error;
 
     tables = face->toc.tables;
     for ( n = 0; n < toc->count; n++ )
@@ -237,8 +242,8 @@ THE SOFTWARE.
           if ( tables[i].type == (FT_UInt)( 1 << j ) )
             name = tableNames[j];
 
-        FT_TRACE4(( "  %d: type=%s, format=0x%X, "
-                    "size=%ld (0x%lX), offset=%ld (0x%lX)\n",
+        FT_TRACE4(( "  %d: type=%s, format=0x%X,"
+                    " size=%ld (0x%lX), offset=%ld (0x%lX)\n",
                     i, name,
                     tables[i].format,
                     tables[i].size, tables[i].size,
@@ -348,6 +353,17 @@ THE SOFTWARE.
       metric->attributes       = 0;
     }
 
+    FT_TRACE5(( " width=%d,"
+                " lsb=%d, rsb=%d,"
+                " ascent=%d, descent=%d,"
+                " attributes=%d\n",
+                metric->characterWidth,
+                metric->leftSideBearing,
+                metric->rightSideBearing,
+                metric->ascent,
+                metric->descent,
+                metric->attributes ));
+
   Exit:
     return error;
   }
@@ -466,7 +482,7 @@ THE SOFTWARE.
   {
     PCF_ParseProperty  props      = NULL;
     PCF_Property       properties = NULL;
-    FT_ULong           nprops, i;
+    FT_ULong           nprops, orig_nprops, i;
     FT_ULong           format, size;
     FT_Error           error;
     FT_Memory          memory     = FT_FACE( face )->memory;
@@ -486,32 +502,43 @@ THE SOFTWARE.
     if ( FT_READ_ULONG_LE( format ) )
       goto Bail;
 
-    FT_TRACE4(( "pcf_get_properties:\n" ));
-
-    FT_TRACE4(( "  format = %ld\n", format ));
+    FT_TRACE4(( "pcf_get_properties:\n"
+                "  format: 0x%lX (%s)\n",
+                format,
+                PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
 
     if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
       goto Bail;
 
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-      (void)FT_READ_ULONG( nprops );
+      (void)FT_READ_ULONG( orig_nprops );
     else
-      (void)FT_READ_ULONG_LE( nprops );
+      (void)FT_READ_ULONG_LE( orig_nprops );
     if ( error )
       goto Bail;
 
-    FT_TRACE4(( "  nprop = %d (truncate %d props)\n",
-                (int)nprops, nprops - (FT_ULong)(int)nprops ));
-
-    nprops = (FT_ULong)(int)nprops;
+    FT_TRACE4(( "  number of properties: %ld\n", orig_nprops ));
 
     /* rough estimate */
-    if ( nprops > size / PCF_PROPERTY_SIZE )
+    if ( orig_nprops > size / PCF_PROPERTY_SIZE )
     {
       error = FT_THROW( Invalid_Table );
       goto Bail;
     }
 
+    /* as a heuristic limit to avoid excessive allocation in */
+    /* gzip bombs (i.e., very small, invalid input data that */
+    /* pretends to expand to an insanely large file) we only */
+    /* load the first 256 properties                         */
+    if ( orig_nprops > 256 )
+    {
+      FT_TRACE0(( "pcf_get_properties:"
+                  " only loading first 256 properties\n" ));
+      nprops = 256;
+    }
+    else
+      nprops = orig_nprops;
+
     face->nprops = (int)nprops;
 
     if ( FT_NEW_ARRAY( props, nprops ) )
@@ -531,14 +558,23 @@ THE SOFTWARE.
       }
     }
 
+    /* this skip will only work if we really have an extremely large */
+    /* number of properties; it will fail for fake data, avoiding an */
+    /* unnecessarily large allocation later on                       */
+    if ( FT_STREAM_SKIP( ( orig_nprops - nprops ) * PCF_PROPERTY_SIZE ) )
+    {
+      error = FT_THROW( Invalid_Stream_Skip );
+      goto Bail;
+    }
+
     /* pad the property array                                            */
     /*                                                                   */
     /* clever here - nprops is the same as the number of odd-units read, */
     /* as only isStringProp are odd length   (Keith Packard)             */
     /*                                                                   */
-    if ( nprops & 3 )
+    if ( orig_nprops & 3 )
     {
-      i = 4 - ( nprops & 3 );
+      i = 4 - ( orig_nprops & 3 );
       if ( FT_STREAM_SKIP( i ) )
       {
         error = FT_THROW( Invalid_Stream_Skip );
@@ -553,15 +589,24 @@ THE SOFTWARE.
     if ( error )
       goto Bail;
 
-    FT_TRACE4(( "  string_size = %ld\n", string_size ));
+    FT_TRACE4(( "  string size: %ld\n", string_size ));
 
     /* rough estimate */
-    if ( string_size > size - nprops * PCF_PROPERTY_SIZE )
+    if ( string_size > size - orig_nprops * PCF_PROPERTY_SIZE )
     {
       error = FT_THROW( Invalid_Table );
       goto Bail;
     }
 
+    /* the strings in the `strings' array are PostScript strings, */
+    /* which can have a maximum length of 65536 characters each   */
+    if ( string_size > 16777472 )   /* 256 * (65536 + 1) */
+    {
+      FT_TRACE0(( "pcf_get_properties:"
+                  " loading only 16777472 bytes of strings array\n" ));
+      string_size = 16777472;
+    }
+
     /* allocate one more byte so that we have a final null byte */
     if ( FT_NEW_ARRAY( strings, string_size + 1 ) )
       goto Bail;
@@ -575,6 +620,7 @@ THE SOFTWARE.
 
     face->properties = properties;
 
+    FT_TRACE4(( "\n" ));
     for ( i = 0; i < nprops; i++ )
     {
       FT_Long  name_offset = props[i].name;
@@ -637,7 +683,7 @@ THE SOFTWARE.
     FT_Memory   memory  = FT_FACE( face )->memory;
     FT_ULong    format, size;
     PCF_Metric  metrics = NULL;
-    FT_ULong    nmetrics, i;
+    FT_ULong    nmetrics, orig_nmetrics, i;
 
 
     error = pcf_seek_to_table_type( stream,
@@ -652,6 +698,13 @@ THE SOFTWARE.
     if ( FT_READ_ULONG_LE( format ) )
       goto Bail;
 
+    FT_TRACE4(( "pcf_get_metrics:\n"
+                "  format: 0x%lX (%s, %s)\n",
+                format,
+                PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB",
+                PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ?
+                  "compressed" : "uncompressed" ));
+
     if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )     &&
          !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
       return FT_THROW( Invalid_File_Format );
@@ -659,61 +712,70 @@ THE SOFTWARE.
     if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
     {
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-        (void)FT_READ_ULONG( nmetrics );
+        (void)FT_READ_ULONG( orig_nmetrics );
       else
-        (void)FT_READ_ULONG_LE( nmetrics );
+        (void)FT_READ_ULONG_LE( orig_nmetrics );
     }
     else
     {
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-        (void)FT_READ_USHORT( nmetrics );
+        (void)FT_READ_USHORT( orig_nmetrics );
       else
-        (void)FT_READ_USHORT_LE( nmetrics );
+        (void)FT_READ_USHORT_LE( orig_nmetrics );
     }
     if ( error )
       return FT_THROW( Invalid_File_Format );
 
-    face->nmetrics = nmetrics;
-
-    if ( !nmetrics )
-      return FT_THROW( Invalid_Table );
-
-    FT_TRACE4(( "pcf_get_metrics:\n" ));
-
-    FT_TRACE4(( "  number of metrics: %d\n", nmetrics ));
+    FT_TRACE4(( "  number of metrics: %ld\n", orig_nmetrics ));
 
     /* rough estimate */
     if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
     {
-      if ( nmetrics > size / PCF_METRIC_SIZE )
+      if ( orig_nmetrics > size / PCF_METRIC_SIZE )
         return FT_THROW( Invalid_Table );
     }
     else
     {
-      if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
+      if ( orig_nmetrics > size / PCF_COMPRESSED_METRIC_SIZE )
         return FT_THROW( Invalid_Table );
     }
 
+    if ( !orig_nmetrics )
+      return FT_THROW( Invalid_Table );
+
+    /* PCF is a format from ancient times; Unicode was in its       */
+    /* infancy, and widely used two-byte character sets for CJK     */
+    /* scripts (Big 5, GB 2312, JIS X 0208, etc.) did have at most  */
+    /* 15000 characters.  Even the more exotic CNS 11643 and CCCII  */
+    /* standards, which were essentially three-byte character sets, */
+    /* provided less then 65536 assigned characters.                */
+    /*                                                              */
+    /* While technically possible to have a larger number of glyphs */
+    /* in PCF files, we thus limit the number to 65536.             */
+    if ( orig_nmetrics > 65536 )
+    {
+      FT_TRACE0(( "pcf_get_metrics:"
+                  " only loading first 65536 metrics\n" ));
+      nmetrics = 65536;
+    }
+    else
+      nmetrics = orig_nmetrics;
+
+    face->nmetrics = nmetrics;
+
     if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
-      return FT_THROW( Out_Of_Memory );
+      return error;
 
     metrics = face->metrics;
+
+    FT_TRACE4(( "\n" ));
     for ( i = 0; i < nmetrics; i++, metrics++ )
     {
+      FT_TRACE5(( "  idx %ld:", i ));
       error = pcf_get_metric( stream, format, metrics );
 
       metrics->bits = 0;
 
-      FT_TRACE5(( "  idx %d: width=%d, "
-                  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
-                  i,
-                  metrics->characterWidth,
-                  metrics->leftSideBearing,
-                  metrics->rightSideBearing,
-                  metrics->ascent,
-                  metrics->descent,
-                  metrics->attributes ));
-
       if ( error )
         break;
 
@@ -721,7 +783,7 @@ THE SOFTWARE.
       /* compute a glyph's bitmap dimensions, thus setting them to zero in */
       /* case of an error disables this particular glyph only              */
       if ( metrics->rightSideBearing < metrics->leftSideBearing ||
-           metrics->ascent + metrics->descent < 0               )
+           metrics->ascent < -metrics->descent                  )
       {
         metrics->characterWidth   = 0;
         metrics->leftSideBearing  = 0;
@@ -751,7 +813,7 @@ THE SOFTWARE.
     FT_Long*   offsets = NULL;
     FT_Long    bitmapSizes[GLYPHPADOPTIONS];
     FT_ULong   format, size;
-    FT_ULong   nbitmaps, i, sizebitmaps = 0;
+    FT_ULong   nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
 
 
     error = pcf_seek_to_table_type( stream,
@@ -769,18 +831,40 @@ THE SOFTWARE.
 
     format = FT_GET_ULONG_LE();
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-      nbitmaps  = FT_GET_ULONG();
+      orig_nbitmaps = FT_GET_ULONG();
     else
-      nbitmaps  = FT_GET_ULONG_LE();
+      orig_nbitmaps = FT_GET_ULONG_LE();
 
     FT_Stream_ExitFrame( stream );
 
+    FT_TRACE4(( "pcf_get_bitmaps:\n"
+                "  format: 0x%lX\n"
+                "          (%s, %s,\n"
+                "           padding=%d bits, scanning=%d bits)\n",
+                format,
+                PCF_BYTE_ORDER( format ) == MSBFirst
+                  ? "most significant byte first"
+                  : "least significant byte first",
+                PCF_BIT_ORDER( format ) == MSBFirst
+                  ? "most significant bit first"
+                  : "least significant bit first",
+                8 << PCF_GLYPH_PAD_INDEX( format ),
+                8 << PCF_SCAN_UNIT_INDEX( format ) ));
+
     if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
       return FT_THROW( Invalid_File_Format );
 
-    FT_TRACE4(( "pcf_get_bitmaps:\n" ));
+    FT_TRACE4(( "  number of bitmaps: %ld\n", orig_nbitmaps ));
 
-    FT_TRACE4(( "  number of bitmaps: %d\n", nbitmaps ));
+    /* see comment in `pcf_get_metrics' */
+    if ( orig_nbitmaps > 65536 )
+    {
+      FT_TRACE0(( "pcf_get_bitmaps:"
+                  " only loading first 65536 bitmaps\n" ));
+      nbitmaps = 65536;
+    }
+    else
+      nbitmaps = orig_nbitmaps;
 
     if ( nbitmaps != face->nmetrics )
       return FT_THROW( Invalid_File_Format );
@@ -788,6 +872,7 @@ THE SOFTWARE.
     if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
       return error;
 
+    FT_TRACE5(( "\n" ));
     for ( i = 0; i < nbitmaps; i++ )
     {
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
@@ -795,7 +880,7 @@ THE SOFTWARE.
       else
         (void)FT_READ_LONG_LE( offsets[i] );
 
-      FT_TRACE5(( "  bitmap %d: offset %ld (0x%lX)\n",
+      FT_TRACE5(( "  bitmap %ld: offset %ld (0x%lX)\n",
                   i, offsets[i], offsets[i] ));
     }
     if ( error )
@@ -812,17 +897,19 @@ THE SOFTWARE.
 
       sizebitmaps = (FT_ULong)bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
 
-      FT_TRACE4(( "  padding %d implies a size of %ld\n",
-                  i, bitmapSizes[i] ));
+      FT_TRACE4(( "  %ld-bit padding implies a size of %ld\n",
+                  8 << i, bitmapSizes[i] ));
     }
 
-    FT_TRACE4(( "  %d bitmaps, padding index %ld\n",
+    FT_TRACE4(( "  %ld bitmaps, using %ld-bit padding\n",
                 nbitmaps,
-                PCF_GLYPH_PAD_INDEX( format ) ));
-    FT_TRACE4(( "  bitmap size = %d\n", sizebitmaps ));
+                8 << PCF_GLYPH_PAD_INDEX( format ) ));
+    FT_TRACE4(( "  bitmap size: %ld\n", sizebitmaps ));
 
     FT_UNUSED( sizebitmaps );       /* only used for debugging */
 
+    /* right now, we only check the bitmap offsets; */
+    /* actual bitmaps are only loaded on demand     */
     for ( i = 0; i < nbitmaps; i++ )
     {
       /* rough estimate */
@@ -830,7 +917,7 @@ THE SOFTWARE.
            ( (FT_ULong)offsets[i] > size ) )
       {
         FT_TRACE0(( "pcf_get_bitmaps:"
-                    " invalid offset to bitmap data of glyph %d\n", i ));
+                    " invalid offset to bitmap data of glyph %ld\n", i ));
       }
       else
         face->metrics[i].bits = stream->pos + (FT_ULong)offsets[i];
@@ -894,10 +981,20 @@ THE SOFTWARE.
 
     FT_Stream_ExitFrame( stream );
 
+    FT_TRACE4(( "pcf_get_encodings:\n"
+                "  format: 0x%lX (%s)\n",
+                format,
+                PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" ));
+
     if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
       return FT_THROW( Invalid_File_Format );
 
-    /* sanity checks */
+    FT_TRACE4(( "  firstCol 0x%X, lastCol 0x%X\n"
+                "  firstRow 0x%X, lastRow 0x%X\n",
+                firstCol, lastCol,
+                firstRow, lastRow ));
+
+    /* sanity checks; we limit numbers of rows and columns to 256 */
     if ( firstCol < 0       ||
          firstCol > lastCol ||
          lastCol  > 0xFF    ||
@@ -906,21 +1003,18 @@ THE SOFTWARE.
          lastRow  > 0xFF    )
       return FT_THROW( Invalid_Table );
 
-    FT_TRACE4(( "pdf_get_encodings:\n" ));
-
-    FT_TRACE4(( "  firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
-                firstCol, lastCol, firstRow, lastRow ));
-
     nencoding = (FT_ULong)( lastCol - firstCol + 1 ) *
                 (FT_ULong)( lastRow - firstRow + 1 );
 
     if ( FT_NEW_ARRAY( encoding, nencoding ) )
-      return FT_THROW( Out_Of_Memory );
+      return error;
 
     error = FT_Stream_EnterFrame( stream, 2 * nencoding );
     if ( error )
       goto Bail;
 
+    FT_TRACE5(( "\n" ));
+
     k = 0;
     for ( i = firstRow; i <= lastRow; i++ )
     {
@@ -1029,6 +1123,15 @@ THE SOFTWARE.
     if ( FT_READ_ULONG_LE( format ) )
       goto Bail;
 
+    FT_TRACE4(( "pcf_get_accel%s:\n"
+                "  format: 0x%lX (%s, %s)\n",
+                type == PCF_BDF_ACCELERATORS ? " (getting BDF accelerators)"
+                                             : "",
+                format,
+                PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB",
+                PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ?
+                  "accelerated" : "not accelerated" ));
+
     if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )    &&
          !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
       goto Bail;
@@ -1044,12 +1147,29 @@ THE SOFTWARE.
         goto Bail;
     }
 
+    FT_TRACE5(( "  noOverlap=%s, constantMetrics=%s,"
+                " terminalFont=%s, constantWidth=%s\n"
+                "  inkInside=%s, inkMetrics=%s, drawDirection=%s\n"
+                "  fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n",
+                accel->noOverlap ? "yes" : "no",
+                accel->constantMetrics ? "yes" : "no",
+                accel->terminalFont ? "yes" : "no",
+                accel->constantWidth ? "yes" : "no",
+                accel->inkInside ? "yes" : "no",
+                accel->inkMetrics ? "yes" : "no",
+                accel->drawDirection ? "RTL" : "LTR",
+                accel->fontAscent,
+                accel->fontDescent,
+                accel->maxOverlap ));
+
+    FT_TRACE5(( "  minbounds:" ));
     error = pcf_get_metric( stream,
                             format & ( ~PCF_FORMAT_MASK ),
                             &(accel->minbounds) );
     if ( error )
       goto Bail;
 
+    FT_TRACE5(( "  maxbounds:" ));
     error = pcf_get_metric( stream,
                             format & ( ~PCF_FORMAT_MASK ),
                             &(accel->maxbounds) );
@@ -1058,12 +1178,14 @@ THE SOFTWARE.
 
     if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
     {
+      FT_TRACE5(( "  ink minbounds:" ));
       error = pcf_get_metric( stream,
                               format & ( ~PCF_FORMAT_MASK ),
                               &(accel->ink_minbounds) );
       if ( error )
         goto Bail;
 
+      FT_TRACE5(( "  ink maxbounds:" ));
       error = pcf_get_metric( stream,
                               format & ( ~PCF_FORMAT_MASK ),
                               &(accel->ink_maxbounds) );
@@ -1072,7 +1194,7 @@ THE SOFTWARE.
     }
     else
     {
-      accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
+      accel->ink_minbounds = accel->minbounds;
       accel->ink_maxbounds = accel->maxbounds;
     }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]