📄 bdflib.c
字号:
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. */ /* */ /*************************************************************************/ FT_LOCAL_DEF( FT_Error ) bdf_load_font( FT_Stream stream, FT_Memory extmemory, bdf_options_t* opts, bdf_font_t* *font ) { unsigned long lineno = 0; /* make compiler happy */ _bdf_parse_t *p; FT_Memory memory = extmemory; FT_Error error = BDF_Err_Ok; if ( FT_NEW( p ) ) goto Exit; memory = NULL; p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); p->minlb = 32767; p->memory = extmemory; /* only during font creation */ _bdf_list_init( &p->list, extmemory ); error = _bdf_readstream( stream, _bdf_parse_start, (void *)p, &lineno ); if ( error ) goto Fail; if ( p->font != 0 ) { /* 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; /* If the number of glyphs loaded is not that of the original count, */ /* indicate the difference. */ if ( p->cnt != p->font->glyphs_used + p->font->unencoded_used ) { FT_TRACE2(( "bdf_load_font: " ACMSG15, p->cnt, p->font->glyphs_used + p->font->unencoded_used )); p->font->modified = 1; } /* Once the font has been loaded, adjust the overall font metrics if */ /* necessary. */ if ( p->opts->correct_metrics != 0 && ( p->font->glyphs_used > 0 || p->font->unencoded_used > 0 ) ) { if ( p->maxrb - p->minlb != p->font->bbx.width ) { FT_TRACE2(( "bdf_load_font: " ACMSG3, p->font->bbx.width, p->maxrb - p->mi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -