📄 bdflib.c
字号:
goto Exit; } 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; /* Limit ourselves to 1,114,112 glyphs in the font (this is the */ /* number of code points available in Unicode). */ if ( p->cnt >= 1114112UL ) { error = BDF_Err_Invalid_Argument; goto Exit; } 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 ); if ( error ) goto Exit; glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); p->flags |= _BDF_SWIDTH; goto Exit; } /* Expect the DWIDTH (scalable width) field next. */ if ( ft_memcmp( line, "DWIDTH", 6 ) == 0 ) { error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); if ( !( p->flags & _BDF_SWIDTH ) ) { /* Missing SWIDTH field. Emit an auto correction message and set */ /* the scalable width from the device width. */ FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG9, lineno )); glyph->swidth = (unsigned short)FT_MulDiv( glyph->dwidth, 72000L, (FT_Long)( font->point_size * font->resolution_x ) ); } p->flags |= _BDF_DWIDTH; goto Exit; } /* Expect the BBX field next. */ if ( ft_memcmp( line, "BBX", 3 ) == 0 ) { error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; glyph->bbx.width = _bdf_atos( p->list.field[1], 0, 10 ); glyph->bbx.height = _bdf_atos( p->list.field[2], 0, 10 ); glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); /* 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -