[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'.
This commit is contained in:
parent
348d39c68a
commit
8b755445bb
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2017-01-06 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[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 <wl@gnu.org>
|
||||
|
||||
* src/pcf/pcfdrivr.c (PCF_Face_Init): Trace compression format.
|
||||
|
|
|
@ -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" ));
|
||||
}
|
||||
/* Apparently, the PCF driver loads all properties as signed integers!
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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++ )
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue