📄 bdflib.c
字号:
/* Generate the ascent and descent of the character. */
glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset );
glyph->bbx.descent = (short)( -glyph->bbx.y_offset );
/* Determine the overall font bounding box as the characters are */
/* loaded so corrections can be done later if indicated. */
p->maxas = (short)FT_MAX( glyph->bbx.ascent, p->maxas );
p->maxds = (short)FT_MAX( glyph->bbx.descent, p->maxds );
p->rbearing = (short)( glyph->bbx.width + glyph->bbx.x_offset );
p->maxrb = (short)FT_MAX( p->rbearing, p->maxrb );
p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb );
p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb );
if ( !( p->flags & _BDF_DWIDTH ) )
{
/* Missing DWIDTH field. Emit an auto correction message and set */
/* the device width to the glyph width. */
FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG10, lineno ));
glyph->dwidth = glyph->bbx.width;
}
/* If the BDF_CORRECT_METRICS flag is set, then adjust the SWIDTH */
/* value if necessary. */
if ( p->opts->correct_metrics != 0 )
{
/* Determine the point size of the glyph. */
unsigned short sw = (unsigned short)FT_MulDiv(
glyph->dwidth, 72000L,
(FT_Long)( font->point_size *
font->resolution_x ) );
if ( sw != glyph->swidth )
{
glyph->swidth = sw;
if ( p->glyph_enc == -1 )
_bdf_set_glyph_modified( font->umod,
font->unencoded_used - 1 );
else
_bdf_set_glyph_modified( font->nmod, glyph->encoding );
p->flags |= _BDF_SWIDTH_ADJ;
font->modified = 1;
}
}
p->flags |= _BDF_BBX;
goto Exit;
}
/* And finally, gather up the bitmap. */
if ( ft_memcmp( line, "BITMAP", 6 ) == 0 )
{
unsigned long bitmap_size;
if ( !( p->flags & _BDF_BBX ) )
{
/* Missing BBX field. */
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" ));
error = BDF_Err_Missing_Bbx_Field;
goto Exit;
}
/* Allocate enough space for the bitmap. */
glyph->bpr = ( glyph->bbx.width * p->font->bpp + 7 ) >> 3;
bitmap_size = glyph->bpr * glyph->bbx.height;
if ( bitmap_size > 0xFFFFU )
{
FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG4, lineno ));
error = BDF_Err_Bbx_Too_Big;
goto Exit;
}
else
glyph->bytes = (unsigned short)bitmap_size;
if ( FT_NEW_ARRAY( glyph->bitmap, glyph->bytes ) )
goto Exit;
p->row = 0;
p->flags |= _BDF_BITMAP;
goto Exit;
}
error = BDF_Err_Invalid_File_Format;
Exit:
return error;
}
/* Load the font properties. */
static FT_Error
_bdf_parse_properties( char* line,
unsigned long linelen,
unsigned long lineno,
void* call_data,
void* client_data )
{
unsigned long vlen;
_bdf_line_func_t* next;
_bdf_parse_t* p;
char* name;
char* value;
char nbuf[128];
FT_Error error = BDF_Err_Ok;
FT_UNUSED( lineno );
next = (_bdf_line_func_t *)call_data;
p = (_bdf_parse_t *) client_data;
/* Check for the end of the properties. */
if ( ft_memcmp( 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 */
/* make sure they are set from the font bounding box info. */
/* */
/* This is *always* done regardless of the options, because X11 */
/* requires these two fields to compile fonts. */
if ( bdf_get_font_property( p->font, "FONT_ASCENT" ) == 0 )
{
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 );
if ( error )
goto Exit;
FT_TRACE2(( "_bdf_parse_properties: " ACMSG1, p->font->bbx.ascent ));
p->font->modified = 1;
}
if ( bdf_get_font_property( p->font, "FONT_DESCENT" ) == 0 )
{
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 );
if ( error )
goto Exit;
FT_TRACE2(( "_bdf_parse_properties: " ACMSG2, p->font->bbx.descent ));
p->font->modified = 1;
}
p->flags &= ~_BDF_PROPS;
*next = _bdf_parse_glyphs;
goto Exit;
}
/* Ignore the _XFREE86_GLYPH_RANGES properties. */
if ( ft_memcmp( 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 )
{
name = value = line;
value += 7;
if ( *value )
*value++ = 0;
error = _bdf_add_property( p->font, name, value );
if ( error )
goto Exit;
}
else if ( _bdf_is_atom( line, linelen, &name, &value, p->font ) )
{
error = _bdf_add_property( p->font, name, value );
if ( error )
goto Exit;
}
else
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
name = p->list.field[0];
_bdf_list_shift( &p->list, 1 );
value = _bdf_list_join( &p->list, ' ', &vlen );
error = _bdf_add_property( p->font, name, value );
if ( error )
goto Exit;
}
Exit:
return error;
}
/* Load the font header. */
static FT_Error
_bdf_parse_start( char* line,
unsigned long linelen,
unsigned long lineno,
void* call_data,
void* client_data )
{
unsigned long slen;
_bdf_line_func_t* next;
_bdf_parse_t* p;
bdf_font_t* font;
char *s;
FT_Memory memory = NULL;
FT_Error error = BDF_Err_Ok;
FT_UNUSED( lineno ); /* only used in debug mode */
next = (_bdf_line_func_t *)call_data;
p = (_bdf_parse_t *) client_data;
if ( p->font )
memory = p->font->memory;
/* 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 ( p->opts->keep_comments != 0 && p->font != 0 )
{
linelen -= 7;
s = line + 7;
if ( *s != 0 )
{
s++;
linelen--;
}
error = _bdf_add_comment( p->font, s, linelen );
if ( error )
goto Exit;
/* here font is not defined! */
}
goto Exit;
}
if ( !( p->flags & _BDF_START ) )
{
memory = p->memory;
if ( ft_memcmp( line, "STARTFONT", 9 ) != 0 )
{
/* No STARTFONT field is a good indication of a problem. */
error = BDF_Err_Missing_Startfont_Field;
goto Exit;
}
p->flags = _BDF_START;
font = p->font = 0;
if ( FT_NEW( font ) )
goto Exit;
p->font = font;
font->memory = p->memory;
p->memory = 0;
{ /* setup */
unsigned long i;
bdf_property_t* prop;
error = hash_init( &(font->proptbl), memory );
if ( error )
goto Exit;
for ( i = 0, prop = (bdf_property_t*)_bdf_properties;
i < _num_bdf_properties; i++, prop++ )
{
error = hash_insert( prop->name, (void *)i,
&(font->proptbl), memory );
if ( error )
goto Exit;
}
}
if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) )
goto Exit;
error = hash_init( (hashtable *)p->font->internal,memory );
if ( error )
goto Exit;
p->font->spacing = p->opts->font_spacing;
p->font->default_char = -1;
goto Exit;
}
/* Check for the start of the properties. */
if ( ft_memcmp( line, "STARTPROPERTIES", 15 ) == 0 )
{
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 );
if ( FT_NEW_ARRAY( p->font->props, p->cnt ) )
goto Exit;
p->flags |= _BDF_PROPS;
*next = _bdf_parse_properties;
goto Exit;
}
/* Check for the FONTBOUNDINGBOX field. */
if ( ft_memcmp( line, "FONTBOUNDINGBOX", 15 ) == 0 )
{
if ( !(p->flags & _BDF_SIZE ) )
{
/* Missing the SIZE field. */
FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" ));
error = BDF_Err_Missing_Size_Field;
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
p->font->bbx.width = _bdf_atos( p->list.field[1], 0, 10 );
p->font->bbx.height = _bdf_atos( p->list.field[2], 0, 10 );
p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 );
p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 );
p->font->bbx.ascent = (short)( p->font->bbx.height +
p->font->bbx.y_offset );
p->font->bbx.descent = (short)( -p->font->bbx.y_offset );
p->flags |= _BDF_FONT_BBX;
goto Exit;
}
/* The next thing to check for is the FONT field. */
if ( ft_memcmp( line, "FONT", 4 ) == 0 )
{
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->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 );
if ( error )
goto Exit;
p->flags |= _BDF_FONT_NAME;
goto Exit;
}
/* Check for the SIZE field. */
if ( ft_memcmp( 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;
goto Exit;
}
error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
if ( error )
goto Exit;
p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 );
p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 );
p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 );
/* Check for the bits per pixel field. */
if ( p->list.used == 5 )
{
unsigned short bitcount, i, shift;
p->font->bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 );
/* Only values 1, 2, 4, 8 are allowed. */
shift = p->font->bpp;
bitcount = 0;
for ( i = 0; shift > 0; i++ )
{
if ( shift & 1 )
bitcount = i;
shift >>= 1;
}
shift = (short)( ( bitcount > 3 ) ? 8 : ( 1 << bitcount ) );
if ( p->font->bpp > shift || p->font->bpp != shift )
{
/* select next higher value */
p->font->bpp = (unsigned short)( shift << 1 );
FT_TRACE2(( "_bdf_parse_start: " ACMSG11, p->font->bpp ));
}
}
else
p->font->bpp = 1;
p->flags |= _BDF_SIZE;
goto Exit;
}
error = BDF_Err_Invalid_File_Format;
Exit:
return error;
}
/*************************************************************************/
/* */
/* API.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -