📄 bdf.c
字号:
if ( len > 1 )
{
if ( FT_NEW_ARRAY( fp->value.atom, len ) )
goto Exit;
FT_MEM_COPY( fp->value.atom, value, len );
}
else
fp->value.atom = 0;
break;
case BDF_INTEGER:
fp->value.int32 = _bdf_atol( value, 0, 10 );
break;
case BDF_CARDINAL:
fp->value.card32 = _bdf_atoul( value, 0, 10 );
break;
default:
;
}
goto Exit;
}
/* See whether this property type exists yet or not. */
/* If not, create it. */
hn = hash_lookup( name, &(font->proptbl) );
if ( hn == 0 )
{
error = bdf_create_property( name, BDF_ATOM, font );
if ( error )
goto Exit;
hn = hash_lookup( name, &(font->proptbl) );
}
/* Allocate another property if this is overflow. */
if ( font->props_used == font->props_size )
{
if ( font->props_size == 0 )
{
if ( FT_NEW_ARRAY( font->props, 1 ) )
goto Exit;
}
else
{
if ( FT_RENEW_ARRAY( font->props,
font->props_size,
font->props_size + 1 ) )
goto Exit;
}
fp = font->props + font->props_size;
FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) );
font->props_size++;
}
propid = (unsigned long)hn->data;
if ( propid >= _num_bdf_properties )
prop = font->user_props + ( propid - _num_bdf_properties );
else
prop = (bdf_property_t*)_bdf_properties + propid;
fp = font->props + font->props_used;
fp->name = prop->name;
fp->format = prop->format;
fp->builtin = prop->builtin;
switch ( prop->format )
{
case BDF_ATOM:
if ( value == 0 )
len = 1;
else
len = ft_strlen( value ) + 1;
if ( len > 1 )
{
if ( FT_NEW_ARRAY( fp->value.atom, len ) )
goto Exit;
FT_MEM_COPY( fp->value.atom, value, len );
}
else
fp->value.atom = 0;
break;
case BDF_INTEGER:
fp->value.int32 = _bdf_atol( value, 0, 10 );
break;
case BDF_CARDINAL:
fp->value.card32 = _bdf_atoul( value, 0, 10 );
break;
}
/* 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 ) {
/* Add the property to the font property table. */
error = hash_insert( fp->name,
(void *)font->props_used,
(hashtable *)font->internal,
memory );
if ( error )
goto Exit;
}
font->props_used++;
/* Some special cases need to be handled here. The DEFAULT_CHAR */
/* property needs to be located if it exists in the property list, the */
/* 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 )
font->default_char = fp->value.int32;
else if ( ft_memcmp( name, "FONT_ASCENT", 11 ) == 0 )
font->font_ascent = fp->value.int32;
else if ( ft_memcmp( name, "FONT_DESCENT", 12 ) == 0 )
font->font_descent = fp->value.int32;
else if ( ft_memcmp( name, "SPACING", 7 ) == 0 )
{
if ( fp->value.atom[0] == 'p' || fp->value.atom[0] == 'P' )
font->spacing = BDF_PROPORTIONAL;
else if ( fp->value.atom[0] == 'm' || fp->value.atom[0] == 'M' )
font->spacing = BDF_MONOWIDTH;
else if ( fp->value.atom[0] == 'c' || fp->value.atom[0] == 'C' )
font->spacing = BDF_CHARCELL;
}
Exit:
return error;
}
static const unsigned char nibble_mask[8] =
{
0xFF, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE
};
/* Actually parse the glyph info and bitmaps. */
static FT_Error
_bdf_parse_glyphs( char* line,
unsigned long linelen,
unsigned long lineno,
void* call_data,
void* client_data )
{
int c, mask_index;
char* s;
unsigned char* bp;
unsigned long i, slen, nibbles;
_bdf_parse_t* p;
bdf_glyph_t* glyph;
bdf_font_t* font;
FT_Memory memory;
FT_Error error = BDF_Err_Ok;
FT_UNUSED( call_data );
FT_UNUSED( lineno ); /* only used in debug mode */
p = (_bdf_parse_t *)client_data;
font = p->font;
memory = font->memory;
/* Check for a comment. */
if ( ft_memcmp( line, "COMMENT", 7 ) == 0 )
{
linelen -= 7;
s = line + 7;
if ( *s != 0 )
{
s++;
linelen--;
}
error = _bdf_add_comment( p->font, s, linelen );
goto Exit;
}
/* The very first thing expected is the number of glyphs. */
if ( !( p->flags & _BDF_GLYPHS ) )
{
if ( ft_memcmp( line, "CHARS", 5 ) != 0 )
{
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "CHARS" ));
error = BDF_Err_Missing_Chars_Field;
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 );
/* Make sure the number of glyphs is non-zero. */
if ( p->cnt == 0 )
font->glyphs_size = 64;
if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) )
goto Exit;
p->flags |= _BDF_GLYPHS;
goto Exit;
}
/* Check for the ENDFONT field. */
if ( ft_memcmp( line, "ENDFONT", 7 ) == 0 )
{
/* Sort the glyphs by encoding. */
ft_qsort( (char *)font->glyphs,
font->glyphs_used,
sizeof ( bdf_glyph_t ),
by_encoding );
p->flags &= ~_BDF_START;
goto Exit;
}
/* Check for the ENDCHAR field. */
if ( ft_memcmp( line, "ENDCHAR", 7 ) == 0 )
{
p->glyph_enc = 0;
p->flags &= ~_BDF_GLYPH_BITS;
goto Exit;
}
/* Check to see 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 )
{
/* Set the character name in the parse info first until the */
/* encoding can be checked for an unencoded character. */
FT_FREE( p->glyph_name );
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
_bdf_list_shift( &p->list, 1 );
s = _bdf_list_join( &p->list, ' ', &slen );
if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) )
goto Exit;
FT_MEM_COPY( p->glyph_name, s, slen + 1 );
p->flags |= _BDF_GLYPH;
goto Exit;
}
/* Check for the ENCODING field. */
if ( ft_memcmp( 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;
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
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 )
{
error = BDF_Err_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. */
if ( p->glyph_enc >= 0 )
{
if ( _bdf_glyph_modified( p->have, p->glyph_enc ) )
{
/* Emit a message saying a glyph has been moved to the */
/* unencoded area. */
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG12,
p->glyph_enc, p->glyph_name ));
p->glyph_enc = -1;
font->modified = 1;
}
else
_bdf_set_glyph_modified( p->have, p->glyph_enc );
}
if ( p->glyph_enc >= 0 )
{
/* Make sure there are enough glyphs allocated in case the */
/* number of characters happen to be wrong. */
if ( font->glyphs_used == font->glyphs_size )
{
if ( FT_RENEW_ARRAY( font->glyphs,
font->glyphs_size,
font->glyphs_size + 64 ) )
goto Exit;
font->glyphs_size += 64;
}
glyph = font->glyphs + font->glyphs_used++;
glyph->name = p->glyph_name;
glyph->encoding = p->glyph_enc;
/* Reset the initial glyph info. */
p->glyph_name = 0;
}
else
{
/* Unencoded glyph. Check to see whether it should */
/* be added or not. */
if ( p->opts->keep_unencoded != 0 )
{
/* Allocate the next unencoded glyph. */
if ( font->unencoded_used == font->unencoded_size )
{
if ( FT_RENEW_ARRAY( font->unencoded ,
font->unencoded_size,
font->unencoded_size + 4 ) )
goto Exit;
font->unencoded_size += 4;
}
glyph = font->unencoded + font->unencoded_used;
glyph->name = p->glyph_name;
glyph->encoding = font->unencoded_used++;
}
else
/* Free up the glyph name if the unencoded shouldn't be */
/* kept. */
FT_FREE( p->glyph_name );
p->glyph_name = 0;
}
/* Clear the flags that might be added when width and height are */
/* checked for consistency. */
p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK );
p->flags |= _BDF_ENCODING;
goto Exit;
}
/* Point at the glyph being constructed. */
if ( p->glyph_enc == -1 )
glyph = font->unencoded + ( font->unencoded_used - 1 );
else
glyph = font->glyphs + ( font->glyphs_used - 1 );
/* Check to see whether a bitmap is being constructed. */
if ( p->flags & _BDF_BITMAP )
{
/* If there are more rows than are specified in the glyph metrics, */
/* ignore the remaining lines. */
if ( p->row >= (unsigned long)glyph->bbx.height )
{
if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) )
{
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding ));
p->flags |= _BDF_GLYPH_HEIGHT_CHECK;
font->modified = 1;
}
goto Exit;
}
/* Only collect the number of nibbles indicated by the glyph */
/* metrics. If there are more columns, they are simply ignored. */
nibbles = glyph->bpr << 1;
bp = glyph->bitmap + p->row * glyph->bpr;
for ( i = 0; i < nibbles; i++ )
{
c = line[i];
*bp = (FT_Byte)( ( *bp << 4 ) + a2i[c] );
if ( i + 1 < nibbles && ( i & 1 ) )
*++bp = 0;
}
/* 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 ) )
{
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding ));
p->flags |= _BDF_GLYPH_WIDTH_CHECK;
font->modified = 1;
}
p->row++;
goto Exit;
}
/* Expect the SWIDTH (scalable width) field next. */
if ( ft_memcmp( 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;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -