summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/freetype/src/bdf/bdflib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/freetype/src/bdf/bdflib.c')
-rw-r--r--src/3rdparty/freetype/src/bdf/bdflib.c520
1 files changed, 341 insertions, 179 deletions
diff --git a/src/3rdparty/freetype/src/bdf/bdflib.c b/src/3rdparty/freetype/src/bdf/bdflib.c
index 5fa5868c71..abcfdee7be 100644
--- a/src/3rdparty/freetype/src/bdf/bdflib.c
+++ b/src/3rdparty/freetype/src/bdf/bdflib.c
@@ -1,6 +1,6 @@
/*
* Copyright 2000 Computing Research Labs, New Mexico State University
- * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
+ * Copyright 2001-2014
* Francesco Zappa Nardelli
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -169,6 +169,55 @@
sizeof ( _bdf_properties[0] );
+ /* An auxiliary macro to parse properties, to be used in conditionals. */
+ /* It behaves like `strncmp' but also tests the following character */
+ /* whether it is a whitespace or NULL. */
+ /* `property' is a constant string of length `n' to compare with. */
+#define _bdf_strncmp( name, property, n ) \
+ ( ft_strncmp( name, property, n ) || \
+ !( name[n] == ' ' || \
+ name[n] == '\0' || \
+ name[n] == '\n' || \
+ name[n] == '\r' || \
+ name[n] == '\t' ) )
+
+ /* Auto correction messages. */
+#define ACMSG1 "FONT_ASCENT property missing. " \
+ "Added `FONT_ASCENT %hd'.\n"
+#define ACMSG2 "FONT_DESCENT property missing. " \
+ "Added `FONT_DESCENT %hd'.\n"
+#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n"
+#define ACMSG4 "Font left bearing != actual left bearing. " \
+ "Old: %hd New: %hd.\n"
+#define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n"
+#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n"
+#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n"
+#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n"
+#define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n"
+#define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n"
+#define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n"
+#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n"
+#define ACMSG13 "Glyph %ld extra rows removed.\n"
+#define ACMSG14 "Glyph %ld extra columns removed.\n"
+#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n"
+#define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n"
+
+ /* Error messages. */
+#define ERRMSG1 "[line %ld] Missing `%s' line.\n"
+#define ERRMSG2 "[line %ld] Font header corrupted or missing fields.\n"
+#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields.\n"
+#define ERRMSG4 "[line %ld] BBX too big.\n"
+#define ERRMSG5 "[line %ld] `%s' value too big.\n"
+#define ERRMSG6 "[line %ld] Input line too long.\n"
+#define ERRMSG7 "[line %ld] Font name too long.\n"
+#define ERRMSG8 "[line %ld] Invalid `%s' value.\n"
+#define ERRMSG9 "[line %ld] Invalid keyword.\n"
+
+ /* Debug messages. */
+#define DBGMSG1 " [%6ld] %s" /* no \n */
+#define DBGMSG2 " (0x%lX)\n"
+
+
/*************************************************************************/
/* */
/* Hash table utilities for the properties. */
@@ -217,7 +266,7 @@
{
hashnode* obp = ht->table, *bp, *nbp;
int i, sz = ht->size;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
ht->size <<= 1;
@@ -245,8 +294,8 @@
hash_init( hashtable* ht,
FT_Memory memory )
{
- int sz = INITIAL_HT_SIZE;
- FT_Error error = BDF_Err_Ok;
+ int sz = INITIAL_HT_SIZE;
+ FT_Error error = FT_Err_Ok;
ht->size = sz;
@@ -285,8 +334,9 @@
hashtable* ht,
FT_Memory memory )
{
- hashnode nn, *bp = hash_bucket( key, ht );
- FT_Error error = BDF_Err_Ok;
+ hashnode nn;
+ hashnode* bp = hash_bucket( key, ht );
+ FT_Error error = FT_Err_Ok;
nn = *bp;
@@ -377,7 +427,8 @@
bdf_font_t* font;
bdf_options_t* opts;
- unsigned long have[2048];
+ unsigned long have[34816]; /* must be in sync with `nmod' and `umod' */
+ /* arrays from `bdf_font_t' structure */
_bdf_list_t list;
FT_Memory memory;
@@ -418,20 +469,20 @@
_bdf_list_ensure( _bdf_list_t* list,
unsigned long num_items ) /* same as _bdf_list_t.used */
{
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( num_items > list->size )
{
unsigned long oldsize = list->size; /* same as _bdf_list_t.size */
- unsigned long newsize = oldsize + ( oldsize >> 1 ) + 4;
+ unsigned long newsize = oldsize + ( oldsize >> 1 ) + 5;
unsigned long bigsize = (unsigned long)( FT_INT_MAX / sizeof ( char* ) );
FT_Memory memory = list->memory;
if ( oldsize == bigsize )
{
- error = BDF_Err_Out_Of_Memory;
+ error = FT_THROW( Out_Of_Memory );
goto Exit;
}
else if ( newsize < oldsize || newsize > bigsize )
@@ -470,13 +521,18 @@
}
+ /* An empty string for empty fields. */
+
+ static const char empty[1] = { 0 }; /* XXX eliminate this */
+
+
static char *
_bdf_list_join( _bdf_list_t* list,
int c,
unsigned long *alen )
{
unsigned long i, j;
- char *fp, *dp;
+ char* dp;
*alen = 0;
@@ -487,24 +543,26 @@
dp = list->field[0];
for ( i = j = 0; i < list->used; i++ )
{
- fp = list->field[i];
+ char* fp = list->field[i];
+
+
while ( *fp )
dp[j++] = *fp++;
if ( i + 1 < list->used )
dp[j++] = (char)c;
}
- dp[j] = 0;
+ if ( dp != empty )
+ dp[j] = 0;
*alen = j;
return dp;
}
- /* An empty string for empty fields. */
-
- static const char empty[1] = { 0 }; /* XXX eliminate this */
-
+ /* The code below ensures that we have at least 4 + 1 `field' */
+ /* elements in `list' (which are possibly NULL) so that we */
+ /* don't have to check the number of fields in most cases. */
static FT_Error
_bdf_list_split( _bdf_list_t* list,
@@ -515,11 +573,19 @@
int mult, final_empty;
char *sp, *ep, *end;
char seps[32];
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
/* Initialize the list. */
list->used = 0;
+ if ( list->size )
+ {
+ list->field[0] = (char*)empty;
+ list->field[1] = (char*)empty;
+ list->field[2] = (char*)empty;
+ list->field[3] = (char*)empty;
+ list->field[4] = (char*)empty;
+ }
/* If the line is empty, then simply return. */
if ( linelen == 0 || line[0] == 0 )
@@ -530,7 +596,7 @@
/* this, so an error is signaled. */
if ( separators == 0 || *separators == 0 )
{
- error = BDF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -616,14 +682,14 @@
unsigned long lineno, buf_size;
int refill, hold, to_skip;
ptrdiff_t bytes, start, end, cursor, avail;
- char* buf = 0;
+ char* buf = 0;
FT_Memory memory = stream->memory;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( callback == 0 )
{
- error = BDF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -637,7 +703,6 @@
lineno = 1;
buf[0] = 0;
start = 0;
- end = 0;
avail = 0;
cursor = 0;
refill = 1;
@@ -648,8 +713,9 @@
{
if ( refill )
{
- bytes = (ptrdiff_t)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor,
- (FT_ULong)(buf_size - cursor) );
+ bytes = (ptrdiff_t)FT_Stream_TryRead(
+ stream, (FT_Byte*)buf + cursor,
+ (FT_ULong)( buf_size - cursor ) );
avail = cursor + bytes;
cursor = 0;
refill = 0;
@@ -685,7 +751,8 @@
if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */
{
- error = BDF_Err_Invalid_Argument;
+ FT_ERROR(( "_bdf_readstream: " ERRMSG6, lineno ));
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -700,7 +767,7 @@
{
bytes = avail - start;
- FT_MEM_COPY( buf, buf + start, bytes );
+ FT_MEM_MOVE( buf, buf + start, bytes );
cursor = bytes;
avail -= bytes;
@@ -714,11 +781,15 @@
hold = buf[end];
buf[end] = 0;
- /* XXX: Use encoding independent value for 0x1a */
- if ( buf[start] != '#' && buf[start] != 0x1a && end > start )
+ /* XXX: Use encoding independent value for 0x1A */
+ if ( buf[start] != '#' && buf[start] != 0x1A && end > start )
{
- error = (*cb)( buf + start, end - start, lineno,
+ error = (*cb)( buf + start, (unsigned long)( end - start ), lineno,
(void*)&cb, client_data );
+ /* Redo if we have encountered CHARS without properties. */
+ if ( error == -1 )
+ error = (*cb)( buf + start, (unsigned long)( end - start ), lineno,
+ (void*)&cb, client_data );
if ( error )
break;
}
@@ -752,17 +823,17 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const unsigned char odigits[32] =
{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -770,7 +841,7 @@
static const unsigned char ddigits[32] =
{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -778,16 +849,13 @@
static const unsigned char hdigits[32] =
{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,
- 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
+ 0x7E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
-#define isdigok( m, d ) (m[(d) >> 3] & ( 1 << ( (d) & 7 ) ) )
-
-
/* Routine to convert an ASCII string into an unsigned long integer. */
static unsigned long
_bdf_atoul( char* s,
@@ -825,7 +893,7 @@
s += 2;
}
- for ( v = 0; isdigok( dmap, *s ); s++ )
+ for ( v = 0; sbitset( dmap, *s ); s++ )
v = v * base + a2i[(int)*s];
if ( end != 0 )
@@ -880,7 +948,7 @@
s += 2;
}
- for ( v = 0; isdigok( dmap, *s ); s++ )
+ for ( v = 0; sbitset( dmap, *s ); s++ )
v = v * base + a2i[(int)*s];
if ( end != 0 )
@@ -935,7 +1003,7 @@
s += 2;
}
- for ( v = 0; isdigok( dmap, *s ); s++ )
+ for ( v = 0; sbitset( dmap, *s ); s++ )
v = (short)( v * base + a2i[(int)*s] );
if ( end != 0 )
@@ -974,10 +1042,10 @@
size_t n;
bdf_property_t* p;
FT_Memory memory = font->memory;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
- /* First check to see if the property has */
+ /* First check whether the property has */
/* already been added or not. If it has, then */
/* simply ignore it. */
if ( hash_lookup( name, &(font->proptbl) ) )
@@ -993,7 +1061,7 @@
n = ft_strlen( name ) + 1;
if ( n > FT_ULONG_MAX )
- return BDF_Err_Invalid_Argument;
+ return FT_THROW( Invalid_Argument );
if ( FT_NEW_ARRAY( p->name, n ) )
goto Exit;
@@ -1073,33 +1141,6 @@
#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL
- /* Auto correction messages. */
-#define ACMSG1 "FONT_ASCENT property missing. " \
- "Added \"FONT_ASCENT %hd\".\n"
-#define ACMSG2 "FONT_DESCENT property missing. " \
- "Added \"FONT_DESCENT %hd\".\n"
-#define ACMSG3 "Font width != actual width. Old: %hd New: %hd.\n"
-#define ACMSG4 "Font left bearing != actual left bearing. " \
- "Old: %hd New: %hd.\n"
-#define ACMSG5 "Font ascent != actual ascent. Old: %hd New: %hd.\n"
-#define ACMSG6 "Font descent != actual descent. Old: %hd New: %hd.\n"
-#define ACMSG7 "Font height != actual height. Old: %hd New: %hd.\n"
-#define ACMSG8 "Glyph scalable width (SWIDTH) adjustments made.\n"
-#define ACMSG9 "SWIDTH field missing at line %ld. Set automatically.\n"
-#define ACMSG10 "DWIDTH field missing at line %ld. Set to glyph width.\n"
-#define ACMSG11 "SIZE bits per pixel field adjusted to %hd.\n"
-#define ACMSG12 "Duplicate encoding %ld (%s) changed to unencoded.\n"
-#define ACMSG13 "Glyph %ld extra rows removed.\n"
-#define ACMSG14 "Glyph %ld extra columns removed.\n"
-#define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n"
-
- /* Error messages. */
-#define ERRMSG1 "[line %ld] Missing \"%s\" line.\n"
-#define ERRMSG2 "[line %ld] Font header corrupted or missing fields.\n"
-#define ERRMSG3 "[line %ld] Font glyphs corrupted or missing fields.\n"
-#define ERRMSG4 "[line %ld] BBX too big.\n"
-
-
static FT_Error
_bdf_add_comment( bdf_font_t* font,
char* comment,
@@ -1107,7 +1148,7 @@
{
char* cp;
FT_Memory memory = font->memory;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
if ( FT_RENEW_ARRAY( font->comments,
@@ -1131,18 +1172,21 @@
/* default specified in the options. */
static FT_Error
_bdf_set_default_spacing( bdf_font_t* font,
- bdf_options_t* opts )
+ bdf_options_t* opts,
+ unsigned long lineno )
{
size_t len;
char name[256];
_bdf_list_t list;
FT_Memory memory;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
+
+ FT_UNUSED( lineno ); /* only used in debug mode */
if ( font == 0 || font->name == 0 || font->name[0] == 0 )
{
- error = BDF_Err_Invalid_Argument;
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -1156,13 +1200,14 @@
/* Limit ourselves to 256 characters in the font name. */
if ( len >= 256 )
{
- error = BDF_Err_Invalid_Argument;
+ FT_ERROR(( "_bdf_set_default_spacing: " ERRMSG7, lineno ));
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
FT_MEM_COPY( name, font->name, len );
- error = _bdf_list_split( &list, (char *)"-", name, len );
+ error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len );
if ( error )
goto Fail;
@@ -1235,7 +1280,8 @@
ep = line + linelen;
/* Trim the leading whitespace if it exists. */
- *sp++ = 0;
+ if ( *sp )
+ *sp++ = 0;
while ( *sp &&
( *sp == ' ' || *sp == '\t' ) )
sp++;
@@ -1259,18 +1305,21 @@
static FT_Error
- _bdf_add_property( bdf_font_t* font,
- char* name,
- char* value )
+ _bdf_add_property( bdf_font_t* font,
+ char* name,
+ char* value,
+ unsigned long lineno )
{
size_t propid;
hashnode hn;
bdf_property_t *prop, *fp;
FT_Memory memory = font->memory;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
+ FT_UNUSED( lineno ); /* only used in debug mode */
- /* First, check to see if the property already exists in the font. */
+
+ /* First, check whether the property already exists in the font. */
if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 )
{
/* The property already exists in the font, so simply replace */
@@ -1371,7 +1420,8 @@
/* If the property happens to be a comment, then it doesn't need */
/* to be added to the internal hash table. */
- if ( ft_memcmp( name, "COMMENT", 7 ) != 0 ) {
+ if ( _bdf_strncmp( name, "COMMENT", 7 ) != 0 )
+ {
/* Add the property to the font property table. */
error = hash_insert( fp->name,
font->props_used,
@@ -1388,17 +1438,18 @@
/* FONT_ASCENT and FONT_DESCENT need to be assigned if they are */
/* present, and the SPACING property should override the default */
/* spacing. */
- if ( ft_memcmp( name, "DEFAULT_CHAR", 12 ) == 0 )
+ if ( _bdf_strncmp( name, "DEFAULT_CHAR", 12 ) == 0 )
font->default_char = fp->value.l;
- else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 )
+ else if ( _bdf_strncmp( name, "FONT_ASCENT", 11 ) == 0 )
font->font_ascent = fp->value.l;
- else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 )
+ else if ( _bdf_strncmp( name, "FONT_DESCENT", 12 ) == 0 )
font->font_descent = fp->value.l;
- else if ( ft_memcmp( name, "SPACING", 7 ) == 0 )
+ else if ( _bdf_strncmp( name, "SPACING", 7 ) == 0 )
{
if ( !fp->value.atom )
{
- error = BDF_Err_Invalid_File_Format;
+ FT_ERROR(( "_bdf_add_property: " ERRMSG8, lineno, "SPACING" ));
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1439,7 +1490,7 @@
bdf_font_t* font;
FT_Memory memory;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( call_data );
FT_UNUSED( lineno ); /* only used in debug mode */
@@ -1451,7 +1502,7 @@
memory = font->memory;
/* Check for a comment. */
- if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
+ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
linelen -= 7;
@@ -1468,10 +1519,10 @@
/* The very first thing expected is the number of glyphs. */
if ( !( p->flags & _BDF_GLYPHS ) )
{
- if ( ft_memcmp( line, "CHARS", 5 ) != 0 )
+ if ( _bdf_strncmp( line, "CHARS", 5 ) != 0 )
{
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" ));
- error = BDF_Err_Missing_Chars_Field;
+ error = FT_THROW( Missing_Chars_Field );
goto Exit;
}
@@ -1486,9 +1537,10 @@
/* Limit ourselves to 1,114,112 glyphs in the font (this is the */
/* number of code points available in Unicode). */
- if ( p->cnt >= 1114112UL )
+ if ( p->cnt >= 0x110000UL )
{
- error = BDF_Err_Invalid_Argument;
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "CHARS" ));
+ error = FT_THROW( Invalid_Argument );
goto Exit;
}
@@ -1501,8 +1553,16 @@
}
/* Check for the ENDFONT field. */
- if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 )
+ if ( _bdf_strncmp( line, "ENDFONT", 7 ) == 0 )
{
+ if ( p->flags & _BDF_GLYPH_BITS )
+ {
+ /* Missing ENDCHAR field. */
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" ));
+ error = FT_THROW( Corrupted_Font_Glyphs );
+ goto Exit;
+ }
+
/* Sort the glyphs by encoding. */
ft_qsort( (char *)font->glyphs,
font->glyphs_used,
@@ -1515,7 +1575,7 @@
}
/* Check for the ENDCHAR field. */
- if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 )
+ if ( _bdf_strncmp( line, "ENDCHAR", 7 ) == 0 )
{
p->glyph_enc = 0;
p->flags &= ~_BDF_GLYPH_BITS;
@@ -1523,15 +1583,15 @@
goto Exit;
}
- /* Check to see whether a glyph is being scanned but should be */
- /* ignored because it is an unencoded glyph. */
+ /* Check whether a glyph is being scanned but should be */
+ /* ignored because it is an unencoded glyph. */
if ( ( p->flags & _BDF_GLYPH ) &&
p->glyph_enc == -1 &&
p->opts->keep_unencoded == 0 )
goto Exit;
/* Check for the STARTCHAR field. */
- if ( ft_memcmp( line, "STARTCHAR", 9 ) == 0 )
+ if ( _bdf_strncmp( line, "STARTCHAR", 9 ) == 0 )
{
/* Set the character name in the parse info first until the */
/* encoding can be checked for an unencoded character. */
@@ -1547,7 +1607,8 @@
if ( !s )
{
- error = BDF_Err_Invalid_File_Format;
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG8, lineno, "STARTCHAR" ));
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1558,17 +1619,19 @@
p->flags |= _BDF_GLYPH;
+ FT_TRACE4(( DBGMSG1, lineno, s ));
+
goto Exit;
}
/* Check for the ENCODING field. */
- if ( ft_memcmp( line, "ENCODING", 8 ) == 0 )
+ if ( _bdf_strncmp( line, "ENCODING", 8 ) == 0 )
{
if ( !( p->flags & _BDF_GLYPH ) )
{
/* Missing STARTCHAR field. */
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" ));
- error = BDF_Err_Missing_Startchar_Field;
+ error = FT_THROW( Missing_Startchar_Field );
goto Exit;
}
@@ -1578,17 +1641,34 @@
p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 );
- /* Check that the encoding is in the range [0,65536] because */
- /* otherwise p->have (a bitmap with static size) overflows. */
- if ( (size_t)p->glyph_enc >= sizeof ( p->have ) * 8 )
+ /* Normalize negative encoding values. The specification only */
+ /* allows -1, but we can be more generous here. */
+ if ( p->glyph_enc < -1 )
+ p->glyph_enc = -1;
+
+ /* Check for alternative encoding format. */
+ if ( p->glyph_enc == -1 && p->list.used > 2 )
+ p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 );
+
+ if ( p->glyph_enc < -1 )
+ p->glyph_enc = -1;
+
+ FT_TRACE4(( DBGMSG2, p->glyph_enc ));
+
+ /* Check that the encoding is in the Unicode range because */
+ /* otherwise p->have (a bitmap with static size) overflows. */
+ if ( p->glyph_enc > 0 &&
+ (size_t)p->glyph_enc >= sizeof ( p->have ) /
+ sizeof ( unsigned long ) * 32 )
{
- error = BDF_Err_Invalid_File_Format;
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "ENCODING" ));
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
- /* Check to see whether this encoding has already been encountered. */
- /* If it has then change it to unencoded so it gets added if */
- /* indicated. */
+ /* Check whether this encoding has already been encountered. */
+ /* If it has then change it to unencoded so it gets added if */
+ /* indicated. */
if ( p->glyph_enc >= 0 )
{
if ( _bdf_glyph_modified( p->have, p->glyph_enc ) )
@@ -1627,8 +1707,8 @@
}
else
{
- /* Unencoded glyph. Check to see whether it should */
- /* be added or not. */
+ /* Unencoded glyph. Check whether it should */
+ /* be added or not. */
if ( p->opts->keep_unencoded != 0 )
{
/* Allocate the next unencoded glyph. */
@@ -1669,7 +1749,7 @@
else
glyph = font->glyphs + ( font->glyphs_used - 1 );
- /* Check to see whether a bitmap is being constructed. */
+ /* Check whether a bitmap is being constructed. */
if ( p->flags & _BDF_BITMAP )
{
/* If there are more rows than are specified in the glyph metrics, */
@@ -1694,19 +1774,32 @@
for ( i = 0; i < nibbles; i++ )
{
c = line[i];
+ if ( !sbitset( hdigits, c ) )
+ break;
*bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] );
if ( i + 1 < nibbles && ( i & 1 ) )
*++bp = 0;
}
+ /* If any line has not enough columns, */
+ /* indicate they have been padded with zero bits. */
+ if ( i < nibbles &&
+ !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) )
+ {
+ FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding ));
+ p->flags |= _BDF_GLYPH_WIDTH_CHECK;
+ font->modified = 1;
+ }
+
/* Remove possible garbage at the right. */
mask_index = ( glyph->bbx.width * p->font->bpp ) & 7;
if ( glyph->bbx.width )
*bp &= nibble_mask[mask_index];
/* If any line has extra columns, indicate they have been removed. */
- if ( ( line[nibbles] == '0' || a2i[(int)line[nibbles]] != 0 ) &&
- !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) )
+ if ( i == nibbles &&
+ sbitset( hdigits, line[nibbles] ) &&
+ !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) )
{
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding ));
p->flags |= _BDF_GLYPH_WIDTH_CHECK;
@@ -1718,15 +1811,10 @@
}
/* Expect the SWIDTH (scalable width) field next. */
- if ( ft_memcmp( line, "SWIDTH", 6 ) == 0 )
+ if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
{
if ( !( p->flags & _BDF_ENCODING ) )
- {
- /* Missing ENCODING field. */
- FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" ));
- error = BDF_Err_Missing_Encoding_Field;
- goto Exit;
- }
+ goto Missing_Encoding;
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
@@ -1739,8 +1827,11 @@
}
/* Expect the DWIDTH (scalable width) field next. */
- if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 )
+ if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 )
{
+ if ( !( p->flags & _BDF_ENCODING ) )
+ goto Missing_Encoding;
+
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
@@ -1764,8 +1855,11 @@
}
/* Expect the BBX field next. */
- if ( ft_memcmp( line, "BBX", 3 ) == 0 )
+ if ( _bdf_strncmp( line, "BBX", 3 ) == 0 )
{
+ if ( !( p->flags & _BDF_ENCODING ) )
+ goto Missing_Encoding;
+
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
@@ -1829,7 +1923,7 @@
}
/* And finally, gather up the bitmap. */
- if ( ft_memcmp( line, "BITMAP", 6 ) == 0 )
+ if ( _bdf_strncmp( line, "BITMAP", 6 ) == 0 )
{
unsigned long bitmap_size;
@@ -1838,18 +1932,18 @@
{
/* Missing BBX field. */
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" ));
- error = BDF_Err_Missing_Bbx_Field;
+ error = FT_THROW( Missing_Bbx_Field );
goto Exit;
}
/* Allocate enough space for the bitmap. */
- glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3;
+ glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3;
bitmap_size = glyph->bpr * glyph->bbx.height;
- if ( bitmap_size > 0xFFFFU )
+ if ( glyph->bpr > 0xFFFFU || bitmap_size > 0xFFFFU )
{
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno ));
- error = BDF_Err_Bbx_Too_Big;
+ error = FT_THROW( Bbx_Too_Big );
goto Exit;
}
else
@@ -1864,9 +1958,19 @@
goto Exit;
}
- error = BDF_Err_Invalid_File_Format;
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG9, lineno ));
+ error = FT_THROW( Invalid_File_Format );
+ goto Exit;
+
+ Missing_Encoding:
+ /* Missing ENCODING field. */
+ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENCODING" ));
+ error = FT_THROW( Missing_Encoding_Field );
Exit:
+ if ( error && ( p->flags & _BDF_GLYPH ) )
+ FT_FREE( p->glyph_name );
+
return error;
}
@@ -1885,7 +1989,7 @@
char* name;
char* value;
char nbuf[128];
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( lineno );
@@ -1894,7 +1998,7 @@
p = (_bdf_parse_t *) client_data;
/* Check for the end of the properties. */
- if ( ft_memcmp( line, "ENDPROPERTIES", 13 ) == 0 )
+ if ( _bdf_strncmp( line, "ENDPROPERTIES", 13 ) == 0 )
{
/* If the FONT_ASCENT or FONT_DESCENT properties have not been */
/* encountered yet, then make sure they are added as properties and */
@@ -1906,7 +2010,8 @@
{
p->font->font_ascent = p->font->bbx.ascent;
ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
- error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", nbuf );
+ error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
+ nbuf, lineno );
if ( error )
goto Exit;
@@ -1918,7 +2023,8 @@
{
p->font->font_descent = p->font->bbx.descent;
ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
- error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", nbuf );
+ error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
+ nbuf, lineno );
if ( error )
goto Exit;
@@ -1933,24 +2039,24 @@
}
/* Ignore the _XFREE86_GLYPH_RANGES properties. */
- if ( ft_memcmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 )
+ if ( _bdf_strncmp( line, "_XFREE86_GLYPH_RANGES", 21 ) == 0 )
goto Exit;
/* Handle COMMENT fields and properties in a special way to preserve */
/* the spacing. */
- if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
+ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
name = value = line;
value += 7;
if ( *value )
*value++ = 0;
- error = _bdf_add_property( p->font, name, value );
+ error = _bdf_add_property( p->font, name, value, lineno );
if ( error )
goto Exit;
}
else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) )
{
- error = _bdf_add_property( p->font, name, value );
+ error = _bdf_add_property( p->font, name, value, lineno );
if ( error )
goto Exit;
}
@@ -1964,7 +2070,7 @@
_bdf_list_shift( &p->list, 1 );
value = _bdf_list_join( &p->list, ' ', &vlen );
- error = _bdf_add_property( p->font, name, value );
+ error = _bdf_add_property( p->font, name, value, lineno );
if ( error )
goto Exit;
}
@@ -1989,7 +2095,7 @@
char *s;
FT_Memory memory = NULL;
- FT_Error error = BDF_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_UNUSED( lineno ); /* only used in debug mode */
@@ -2002,7 +2108,7 @@
/* Check for a comment. This is done to handle those fonts that have */
/* comments before the STARTFONT line for some reason. */
- if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
+ if ( _bdf_strncmp( line, "COMMENT", 7 ) == 0 )
{
if ( p->opts->keep_comments != 0 && p->font != 0 )
{
@@ -2028,10 +2134,11 @@
{
memory = p->memory;
- if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 )
+ if ( _bdf_strncmp( line, "STARTFONT", 9 ) != 0 )
{
- /* No STARTFONT field is a good indication of a problem. */
- error = BDF_Err_Missing_Startfont_Field;
+ /* we don't emit an error message since this code gets */
+ /* explicitly caught one level higher */
+ error = FT_THROW( Missing_Startfont_Field );
goto Exit;
}
@@ -2075,8 +2182,16 @@
}
/* Check for the start of the properties. */
- if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 )
+ if ( _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 )
{
+ if ( !( p->flags & _BDF_FONT_BBX ) )
+ {
+ /* Missing the FONTBOUNDINGBOX field. */
+ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
+ error = FT_THROW( Missing_Fontboundingbox_Field );
+ goto Exit;
+ }
+
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
@@ -2084,7 +2199,10 @@
p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 );
if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )
+ {
+ p->font->props_size = 0;
goto Exit;
+ }
p->flags |= _BDF_PROPS;
*next = _bdf_parse_properties;
@@ -2093,13 +2211,13 @@
}
/* Check for the FONTBOUNDINGBOX field. */
- if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 )
+ if ( _bdf_strncmp( line, "FONTBOUNDINGBOX", 15 ) == 0 )
{
- if ( !(p->flags & _BDF_SIZE ) )
+ if ( !( p->flags & _BDF_SIZE ) )
{
/* Missing the SIZE field. */
FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" ));
- error = BDF_Err_Missing_Size_Field;
+ error = FT_THROW( Missing_Size_Field );
goto Exit;
}
@@ -2124,7 +2242,7 @@
}
/* The next thing to check for is the FONT field. */
- if ( ft_memcmp( line, "FONT", 4 ) == 0 )
+ if ( _bdf_strncmp( line, "FONT", 4 ) == 0 )
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
@@ -2135,17 +2253,21 @@
if ( !s )
{
- error = BDF_Err_Invalid_File_Format;
+ FT_ERROR(( "_bdf_parse_start: " ERRMSG8, lineno, "FONT" ));
+ error = FT_THROW( Invalid_File_Format );
goto Exit;
}
+ /* Allowing multiple `FONT' lines (which is invalid) doesn't hurt... */
+ FT_FREE( p->font->name );
+
if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) )
goto Exit;
FT_MEM_COPY( p->font->name, s, slen + 1 );
/* If the font name is an XLFD name, set the spacing to the one in */
/* the font name. If there is no spacing fall back on the default. */
- error = _bdf_set_default_spacing( p->font, p->opts );
+ error = _bdf_set_default_spacing( p->font, p->opts, lineno );
if ( error )
goto Exit;
@@ -2155,13 +2277,13 @@
}
/* Check for the SIZE field. */
- if ( ft_memcmp( line, "SIZE", 4 ) == 0 )
+ if ( _bdf_strncmp( line, "SIZE", 4 ) == 0 )
{
if ( !( p->flags & _BDF_FONT_NAME ) )
{
/* Missing the FONT field. */
FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" ));
- error = BDF_Err_Missing_Font_Field;
+ error = FT_THROW( Missing_Font_Field );
goto Exit;
}
@@ -2208,7 +2330,49 @@
goto Exit;
}
- error = BDF_Err_Invalid_File_Format;
+ /* Check for the CHARS field -- font properties are optional */
+ if ( _bdf_strncmp( line, "CHARS", 5 ) == 0 )
+ {
+ char nbuf[128];
+
+
+ if ( !( p->flags & _BDF_FONT_BBX ) )
+ {
+ /* Missing the FONTBOUNDINGBOX field. */
+ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" ));
+ error = FT_THROW( Missing_Fontboundingbox_Field );
+ goto Exit;
+ }
+
+ /* Add the two standard X11 properties which are required */
+ /* for compiling fonts. */
+ p->font->font_ascent = p->font->bbx.ascent;
+ ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
+ error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
+ nbuf, lineno );
+ if ( error )
+ goto Exit;
+ FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));
+
+ p->font->font_descent = p->font->bbx.descent;
+ ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
+ error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
+ nbuf, lineno );
+ if ( error )
+ goto Exit;
+ FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));
+
+ p->font->modified = 1;
+
+ *next = _bdf_parse_glyphs;
+
+ /* A special return value. */
+ error = -1;
+ goto Exit;
+ }
+
+ FT_ERROR(( "_bdf_parse_start: " ERRMSG9, lineno ));
+ error = FT_THROW( Invalid_File_Format );
Exit:
return error;
@@ -2229,10 +2393,10 @@
bdf_font_t* *font )
{
unsigned long lineno = 0; /* make compiler happy */
- _bdf_parse_t *p;
+ _bdf_parse_t *p = NULL;
- FT_Memory memory = extmemory;
- FT_Error error = BDF_Err_Ok;
+ FT_Memory memory = extmemory; /* needed for FT_NEW */
+ FT_Error error = FT_Err_Ok;
if ( FT_NEW( p ) )
@@ -2254,7 +2418,6 @@
{
/* If the font is not proportional, set the font's monowidth */
/* field to the width of the font bounding box. */
- memory = p->font->memory;
if ( p->font->spacing != BDF_PROPORTIONAL )
p->font->monowidth = p->font->bbx.width;
@@ -2320,22 +2483,20 @@
if ( p->flags & _BDF_START )
{
+ /* The ENDFONT field was never reached or did not exist. */
+ if ( !( p->flags & _BDF_GLYPHS ) )
{
- /* The ENDFONT field was never reached or did not exist. */
- if ( !( p->flags & _BDF_GLYPHS ) )
- {
- /* Error happened while parsing header. */
- FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno ));
- error = BDF_Err_Corrupted_Font_Header;
- goto Exit;
- }
- else
- {
- /* Error happened when parsing glyphs. */
- FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno ));
- error = BDF_Err_Corrupted_Font_Glyphs;
- goto Exit;
- }
+ /* Error happened while parsing header. */
+ FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno ));
+ error = FT_THROW( Corrupted_Font_Header );
+ goto Exit;
+ }
+ else
+ {
+ /* Error happened when parsing glyphs. */
+ FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno ));
+ error = FT_THROW( Corrupted_Font_Glyphs );
+ goto Exit;
}
}
@@ -2344,7 +2505,8 @@
/* Make sure the comments are NULL terminated if they exist. */
memory = p->font->memory;
- if ( p->font->comments_len > 0 ) {
+ if ( p->font->comments_len > 0 )
+ {
if ( FT_RENEW_ARRAY( p->font->comments,
p->font->comments_len,
p->font->comments_len + 1 ) )
@@ -2353,8 +2515,8 @@
p->font->comments[p->font->comments_len] = 0;
}
}
- else if ( error == BDF_Err_Ok )
- error = BDF_Err_Invalid_File_Format;
+ else if ( error == FT_Err_Ok )
+ error = FT_THROW( Invalid_File_Format );
*font = p->font;
@@ -2448,8 +2610,8 @@
hash_free( &(font->proptbl), memory );
/* Free up the user defined properties. */
- for (prop = font->user_props, i = 0;
- i < font->nuser_props; i++, prop++ )
+ for ( prop = font->user_props, i = 0;
+ i < font->nuser_props; i++, prop++ )
{
FT_FREE( prop->name );
if ( prop->format == BDF_ATOM )