summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/pcf/pcfread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/pcf/pcfread.c')
-rw-r--r--src/3rdparty/freetype/src/pcf/pcfread.c407
1 files changed, 241 insertions, 166 deletions
diff --git a/src/3rdparty/freetype/src/pcf/pcfread.c b/src/3rdparty/freetype/src/pcf/pcfread.c
index 537da0dc79..2ffe22d71c 100644
--- a/src/3rdparty/freetype/src/pcf/pcfread.c
+++ b/src/3rdparty/freetype/src/pcf/pcfread.c
@@ -37,14 +37,14 @@ THE SOFTWARE.
#include "pcferror.h"
- /*************************************************************************/
- /* */
- /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
- /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
- /* messages during execution. */
- /* */
+ /**************************************************************************
+ *
+ * The macro FT_COMPONENT is used in trace mode. It is an implicit
+ * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+ * messages during execution.
+ */
#undef FT_COMPONENT
-#define FT_COMPONENT trace_pcfread
+#define FT_COMPONENT pcfread
#ifdef FT_DEBUG_LEVEL_TRACE
@@ -178,23 +178,23 @@ THE SOFTWARE.
}
/*
- * We now check whether the `size' and `offset' values are reasonable:
- * `offset' + `size' must not exceed the stream size.
+ * We now check whether the `size' and `offset' values are reasonable:
+ * `offset' + `size' must not exceed the stream size.
*
- * Note, however, that X11's `pcfWriteFont' routine (used by the
- * `bdftopcf' program to create PDF font files) has two special
- * features.
+ * Note, however, that X11's `pcfWriteFont' routine (used by the
+ * `bdftopcf' program to create PCF font files) has two special
+ * features.
*
- * - It always assigns the accelerator table a size of 100 bytes in the
- * TOC, regardless of its real size, which can vary between 34 and 72
- * bytes.
+ * - It always assigns the accelerator table a size of 100 bytes in the
+ * TOC, regardless of its real size, which can vary between 34 and 72
+ * bytes.
*
- * - Due to the way the routine is designed, it ships out the last font
- * table with its real size, ignoring the TOC's size value. Since
- * the TOC size values are always rounded up to a multiple of 4, the
- * difference can be up to three bytes for all tables except the
- * accelerator table, for which the difference can be as large as 66
- * bytes.
+ * - Due to the way the routine is designed, it ships out the last font
+ * table with its real size, ignoring the TOC's size value. Since
+ * the TOC size values are always rounded up to a multiple of 4, the
+ * difference can be up to three bytes for all tables except the
+ * accelerator table, for which the difference can be as large as 66
+ * bytes.
*
*/
@@ -743,33 +743,39 @@ THE SOFTWARE.
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 )
+ /*
+ * 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 65535, taking into account that we
+ * synthesize the metrics of glyph 0 to be a copy of the `default
+ * character', and that 0xFFFF in the encodings array indicates a
+ * missing glyph.
+ */
+ if ( orig_nmetrics > 65534 )
{
FT_TRACE0(( "pcf_get_metrics:"
- " only loading first 65536 metrics\n" ));
- nmetrics = 65536;
+ " only loading first 65534 metrics\n" ));
+ nmetrics = 65534;
}
else
nmetrics = orig_nmetrics;
- face->nmetrics = nmetrics;
+ face->nmetrics = nmetrics + 1;
- if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
+ if ( FT_NEW_ARRAY( face->metrics, face->nmetrics ) )
return error;
- metrics = face->metrics;
+ /* we handle glyph index 0 later on */
+ metrics = face->metrics + 1;
FT_TRACE4(( "\n" ));
- for ( i = 0; i < nmetrics; i++, metrics++ )
+ for ( i = 1; i < face->nmetrics; i++, metrics++ )
{
FT_TRACE5(( " idx %ld:", i ));
error = pcf_get_metric( stream, format, metrics );
@@ -808,12 +814,10 @@ THE SOFTWARE.
pcf_get_bitmaps( FT_Stream stream,
PCF_Face face )
{
- FT_Error error;
- FT_Memory memory = FT_FACE( face )->memory;
- FT_Long* offsets = NULL;
- FT_Long bitmapSizes[GLYPHPADOPTIONS];
- FT_ULong format, size;
- FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
+ FT_Error error;
+ FT_ULong bitmapSizes[GLYPHPADOPTIONS];
+ FT_ULong format, size, pos;
+ FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
error = pcf_seek_to_table_type( stream,
@@ -859,31 +863,46 @@ THE SOFTWARE.
FT_TRACE4(( " number of bitmaps: %ld\n", orig_nbitmaps ));
/* see comment in `pcf_get_metrics' */
- if ( orig_nbitmaps > 65536 )
+ if ( orig_nbitmaps > 65534 )
{
FT_TRACE0(( "pcf_get_bitmaps:"
- " only loading first 65536 bitmaps\n" ));
- nbitmaps = 65536;
+ " only loading first 65534 bitmaps\n" ));
+ nbitmaps = 65534;
}
else
nbitmaps = orig_nbitmaps;
- if ( nbitmaps != face->nmetrics )
+ /* no extra bitmap for glyph 0 */
+ if ( nbitmaps != face->nmetrics - 1 )
return FT_THROW( Invalid_File_Format );
- if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
- return error;
+ /* start position of bitmap data */
+ pos = stream->pos + nbitmaps * 4 + 4 * 4;
FT_TRACE5(( "\n" ));
- for ( i = 0; i < nbitmaps; i++ )
+ for ( i = 1; i <= nbitmaps; i++ )
{
+ FT_ULong offset;
+
+
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
- (void)FT_READ_LONG( offsets[i] );
+ (void)FT_READ_ULONG( offset );
else
- (void)FT_READ_LONG_LE( offsets[i] );
+ (void)FT_READ_ULONG_LE( offset );
+
+ FT_TRACE5(( " bitmap %lu: offset %lu (0x%lX)\n",
+ i, offset, offset ));
- FT_TRACE5(( " bitmap %ld: offset %ld (0x%lX)\n",
- i, offsets[i], offsets[i] ));
+ /* right now, we only check the offset with a rough estimate; */
+ /* actual bitmaps are only loaded on demand */
+ if ( offset > size )
+ {
+ FT_TRACE0(( "pcf_get_bitmaps:"
+ " invalid offset to bitmap data of glyph %lu\n", i ));
+ face->metrics[i].bits = pos;
+ }
+ else
+ face->metrics[i].bits = pos + offset;
}
if ( error )
goto Bail;
@@ -891,62 +910,84 @@ THE SOFTWARE.
for ( i = 0; i < GLYPHPADOPTIONS; i++ )
{
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
- (void)FT_READ_LONG( bitmapSizes[i] );
+ (void)FT_READ_ULONG( bitmapSizes[i] );
else
- (void)FT_READ_LONG_LE( bitmapSizes[i] );
+ (void)FT_READ_ULONG_LE( bitmapSizes[i] );
if ( error )
goto Bail;
- sizebitmaps = (FT_ULong)bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
+ sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
- FT_TRACE4(( " %ld-bit padding implies a size of %ld\n",
+ FT_TRACE4(( " %ld-bit padding implies a size of %lu\n",
8 << i, bitmapSizes[i] ));
}
- FT_TRACE4(( " %ld bitmaps, using %ld-bit padding\n",
+ FT_TRACE4(( " %lu bitmaps, using %ld-bit padding\n",
nbitmaps,
8 << PCF_GLYPH_PAD_INDEX( format ) ));
- FT_TRACE4(( " bitmap size: %ld\n", sizebitmaps ));
+ FT_TRACE4(( " bitmap size: %lu\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 */
- if ( ( offsets[i] < 0 ) ||
- ( (FT_ULong)offsets[i] > size ) )
- {
- FT_TRACE0(( "pcf_get_bitmaps:"
- " invalid offset to bitmap data of glyph %ld\n", i ));
- }
- else
- face->metrics[i].bits = stream->pos + (FT_ULong)offsets[i];
- }
-
face->bitmapsFormat = format;
Bail:
- FT_FREE( offsets );
return error;
}
+ /*
+ * This file uses X11 terminology for PCF data; an `encoding' in X11 speak
+ * is the same as a character code in FreeType speak.
+ */
+#define PCF_ENC_SIZE 10
+
+ static
+ const FT_Frame_Field pcf_enc_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_EncRec
+
+ FT_FRAME_START( PCF_ENC_SIZE ),
+ FT_FRAME_USHORT_LE( firstCol ),
+ FT_FRAME_USHORT_LE( lastCol ),
+ FT_FRAME_USHORT_LE( firstRow ),
+ FT_FRAME_USHORT_LE( lastRow ),
+ FT_FRAME_USHORT_LE( defaultChar ),
+ FT_FRAME_END
+ };
+
+
+ static
+ const FT_Frame_Field pcf_enc_msb_header[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE PCF_EncRec
+
+ FT_FRAME_START( PCF_ENC_SIZE ),
+ FT_FRAME_USHORT( firstCol ),
+ FT_FRAME_USHORT( lastCol ),
+ FT_FRAME_USHORT( firstRow ),
+ FT_FRAME_USHORT( lastRow ),
+ FT_FRAME_USHORT( defaultChar ),
+ FT_FRAME_END
+ };
+
+
static FT_Error
pcf_get_encodings( FT_Stream stream,
PCF_Face face )
{
- FT_Error error;
- FT_Memory memory = FT_FACE( face )->memory;
- FT_ULong format, size;
- int firstCol, lastCol;
- int firstRow, lastRow;
- FT_ULong nencoding;
- FT_UShort encodingOffset;
- int i, j;
- FT_ULong k;
- PCF_Encoding encoding = NULL;
+ FT_Error error;
+ FT_Memory memory = FT_FACE( face )->memory;
+ FT_ULong format, size;
+ PCF_Enc enc = &face->enc;
+ FT_ULong nencoding;
+ FT_UShort* offset;
+ FT_UShort defaultCharRow, defaultCharCol;
+ FT_UShort encodingOffset, defaultCharEncodingOffset;
+ FT_UShort i, j;
+ FT_Byte* pos;
error = pcf_seek_to_table_type( stream,
@@ -956,105 +997,148 @@ THE SOFTWARE.
&format,
&size );
if ( error )
- return error;
+ goto Bail;
- error = FT_Stream_EnterFrame( stream, 14 );
- if ( error )
- return error;
+ if ( FT_READ_ULONG_LE( format ) )
+ goto Bail;
- format = FT_GET_ULONG_LE();
+ 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 ) &&
+ !PCF_FORMAT_MATCH( format, PCF_BDF_ENCODINGS ) )
+ return FT_THROW( Invalid_File_Format );
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
{
- firstCol = FT_GET_SHORT();
- lastCol = FT_GET_SHORT();
- firstRow = FT_GET_SHORT();
- lastRow = FT_GET_SHORT();
- face->defaultChar = FT_GET_SHORT();
+ if ( FT_STREAM_READ_FIELDS( pcf_enc_msb_header, enc ) )
+ goto Bail;
}
else
{
- firstCol = FT_GET_SHORT_LE();
- lastCol = FT_GET_SHORT_LE();
- firstRow = FT_GET_SHORT_LE();
- lastRow = FT_GET_SHORT_LE();
- face->defaultChar = FT_GET_SHORT_LE();
+ if ( FT_STREAM_READ_FIELDS( pcf_enc_header, enc ) )
+ goto Bail;
}
- 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 );
-
FT_TRACE4(( " firstCol 0x%X, lastCol 0x%X\n"
- " firstRow 0x%X, lastRow 0x%X\n",
- firstCol, lastCol,
- firstRow, lastRow ));
+ " firstRow 0x%X, lastRow 0x%X\n"
+ " defaultChar 0x%X\n",
+ enc->firstCol, enc->lastCol,
+ enc->firstRow, enc->lastRow,
+ enc->defaultChar ));
/* sanity checks; we limit numbers of rows and columns to 256 */
- if ( firstCol < 0 ||
- firstCol > lastCol ||
- lastCol > 0xFF ||
- firstRow < 0 ||
- firstRow > lastRow ||
- lastRow > 0xFF )
+ if ( enc->firstCol > enc->lastCol ||
+ enc->lastCol > 0xFF ||
+ enc->firstRow > enc->lastRow ||
+ enc->lastRow > 0xFF )
return FT_THROW( Invalid_Table );
- nencoding = (FT_ULong)( lastCol - firstCol + 1 ) *
- (FT_ULong)( lastRow - firstRow + 1 );
+ nencoding = (FT_ULong)( enc->lastCol - enc->firstCol + 1 ) *
+ (FT_ULong)( enc->lastRow - enc->firstRow + 1 );
- if ( FT_NEW_ARRAY( encoding, nencoding ) )
- return error;
+ if ( FT_NEW_ARRAY( enc->offset, nencoding ) )
+ goto Bail;
error = FT_Stream_EnterFrame( stream, 2 * nencoding );
if ( error )
- goto Bail;
+ goto Exit;
FT_TRACE5(( "\n" ));
- k = 0;
- for ( i = firstRow; i <= lastRow; i++ )
+ defaultCharRow = enc->defaultChar >> 8;
+ defaultCharCol = enc->defaultChar & 0xFF;
+
+ /* validate default character */
+ if ( defaultCharRow < enc->firstRow ||
+ defaultCharRow > enc->lastRow ||
+ defaultCharCol < enc->firstCol ||
+ defaultCharCol > enc->lastCol )
+ {
+ enc->defaultChar = enc->firstRow * 256U + enc->firstCol;
+ FT_TRACE0(( "pcf_get_encodings:"
+ " Invalid default character set to %u\n",
+ enc->defaultChar ));
+
+ defaultCharRow = enc->firstRow;
+ defaultCharCol = enc->firstCol;
+ }
+
+ /*
+ * FreeType mandates that glyph index 0 is the `undefined glyph', which
+ * PCF calls the `default character'. However, FreeType needs glyph
+ * index 0 to be used for the undefined glyph only, which is is not the
+ * case for PCF. For this reason, we add one slot for glyph index 0 and
+ * simply copy the default character to it.
+ *
+ * `stream->cursor' still points to the beginning of the frame; we can
+ * thus easily get the offset to the default character.
+ */
+ pos = stream->cursor +
+ 2 * ( ( defaultCharRow - enc->firstRow ) *
+ ( enc->lastCol - enc->firstCol + 1 ) +
+ defaultCharCol - enc->firstCol );
+
+ if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+ defaultCharEncodingOffset = FT_PEEK_USHORT( pos );
+ else
+ defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos );
+
+ if ( defaultCharEncodingOffset == 0xFFFF )
+ {
+ FT_TRACE0(( "pcf_get_encodings:"
+ " No glyph for default character,\n"
+ " "
+ " setting it to the first glyph of the font\n" ));
+ defaultCharEncodingOffset = 1;
+ }
+ else
+ {
+ defaultCharEncodingOffset++;
+
+ if ( defaultCharEncodingOffset >= face->nmetrics )
+ {
+ FT_TRACE0(( "pcf_get_encodings:"
+ " Invalid glyph index for default character,\n"
+ " "
+ " setting it to the first glyph of the font\n" ));
+ defaultCharEncodingOffset = 1;
+ }
+ }
+
+ /* copy metrics of default character to index 0 */
+ face->metrics[0] = face->metrics[defaultCharEncodingOffset];
+
+ /* now loop over all values */
+ offset = enc->offset;
+ for ( i = enc->firstRow; i <= enc->lastRow; i++ )
{
- for ( j = firstCol; j <= lastCol; j++ )
+ for ( j = enc->firstCol; j <= enc->lastCol; j++ )
{
/* X11's reference implementation uses the equivalent to */
/* `FT_GET_SHORT', however PCF fonts with more than 32768 */
- /* characters (e.g. `unifont.pcf') clearly show that an */
+ /* characters (e.g., `unifont.pcf') clearly show that an */
/* unsigned value is needed. */
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
encodingOffset = FT_GET_USHORT();
else
encodingOffset = FT_GET_USHORT_LE();
- if ( encodingOffset != 0xFFFFU )
- {
- encoding[k].enc = i * 256 + j;
- encoding[k].glyph = encodingOffset;
-
- FT_TRACE5(( " code %d (0x%04X): idx %d\n",
- encoding[k].enc, encoding[k].enc, encoding[k].glyph ));
-
- k++;
- }
+ /* everything is off by 1 due to the artificial glyph 0 */
+ *offset++ = encodingOffset == 0xFFFF ? 0xFFFF
+ : encodingOffset + 1;
}
}
FT_Stream_ExitFrame( stream );
- if ( FT_RENEW_ARRAY( encoding, nencoding, k ) )
- goto Bail;
-
- face->nencodings = k;
- face->encodings = encoding;
-
return error;
+ Exit:
+ FT_FREE( enc->offset );
+
Bail:
- FT_FREE( encoding );
return error;
}
@@ -1228,9 +1312,8 @@ THE SOFTWARE.
PCF_Property prop;
- size_t nn, len;
- char* strings[4] = { NULL, NULL, NULL, NULL };
- size_t lengths[4];
+ const char* strings[4] = { NULL, NULL, NULL, NULL };
+ size_t lengths[4], nn, len;
face->style_flags = 0;
@@ -1242,8 +1325,8 @@ THE SOFTWARE.
{
face->style_flags |= FT_STYLE_FLAG_ITALIC;
strings[2] = ( *(prop->value.atom) == 'O' ||
- *(prop->value.atom) == 'o' ) ? (char *)"Oblique"
- : (char *)"Italic";
+ *(prop->value.atom) == 'o' ) ? "Oblique"
+ : "Italic";
}
prop = pcf_find_property( pcf, "WEIGHT_NAME" );
@@ -1251,20 +1334,20 @@ THE SOFTWARE.
( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
{
face->style_flags |= FT_STYLE_FLAG_BOLD;
- strings[1] = (char*)"Bold";
+ strings[1] = "Bold";
}
prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
if ( prop && prop->isString &&
*(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
- strings[3] = (char*)( prop->value.atom );
+ strings[3] = (const char*)( prop->value.atom );
prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
if ( prop && prop->isString &&
*(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
- strings[0] = (char*)( prop->value.atom );
+ strings[0] = (const char*)( prop->value.atom );
for ( len = 0, nn = 0; nn < 4; nn++ )
{
@@ -1278,7 +1361,7 @@ THE SOFTWARE.
if ( len == 0 )
{
- strings[0] = (char*)"Regular";
+ strings[0] = "Regular";
lengths[0] = ft_strlen( strings[0] );
len = lengths[0] + 1;
}
@@ -1294,7 +1377,7 @@ THE SOFTWARE.
for ( nn = 0; nn < 4; nn++ )
{
- char* src = strings[nn];
+ const char* src = strings[nn];
len = lengths[nn];
@@ -1397,8 +1480,7 @@ THE SOFTWARE.
root->face_flags |= FT_FACE_FLAG_FIXED_SIZES |
- FT_FACE_FLAG_HORIZONTAL |
- FT_FACE_FLAG_FAST_GLYPHS;
+ FT_FACE_FLAG_HORIZONTAL;
if ( face->accel.constantWidth )
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
@@ -1482,14 +1564,7 @@ THE SOFTWARE.
else
root->family_name = NULL;
- /*
- * Note: We shift all glyph indices by +1 since we must
- * respect the convention that glyph 0 always corresponds
- * to the `missing glyph'.
- *
- * This implies bumping the number of `available' glyphs by 1.
- */
- root->num_glyphs = (FT_Long)( face->nmetrics + 1 );
+ root->num_glyphs = (FT_Long)face->nmetrics;
root->num_fixed_sizes = 1;
if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )