📄 pcfread.c
字号:
return error;
Bail:
FT_FREE( encoding );
FT_FREE( tmpEncoding );
return error;
}
static
const FT_Frame_Field pcf_accel_header[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_AccelRec
FT_FRAME_START( 20 ),
FT_FRAME_BYTE ( noOverlap ),
FT_FRAME_BYTE ( constantMetrics ),
FT_FRAME_BYTE ( terminalFont ),
FT_FRAME_BYTE ( constantWidth ),
FT_FRAME_BYTE ( inkInside ),
FT_FRAME_BYTE ( inkMetrics ),
FT_FRAME_BYTE ( drawDirection ),
FT_FRAME_SKIP_BYTES( 1 ),
FT_FRAME_LONG_LE ( fontAscent ),
FT_FRAME_LONG_LE ( fontDescent ),
FT_FRAME_LONG_LE ( maxOverlap ),
FT_FRAME_END
};
static
const FT_Frame_Field pcf_accel_msb_header[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE PCF_AccelRec
FT_FRAME_START( 20 ),
FT_FRAME_BYTE ( noOverlap ),
FT_FRAME_BYTE ( constantMetrics ),
FT_FRAME_BYTE ( terminalFont ),
FT_FRAME_BYTE ( constantWidth ),
FT_FRAME_BYTE ( inkInside ),
FT_FRAME_BYTE ( inkMetrics ),
FT_FRAME_BYTE ( drawDirection ),
FT_FRAME_SKIP_BYTES( 1 ),
FT_FRAME_LONG ( fontAscent ),
FT_FRAME_LONG ( fontDescent ),
FT_FRAME_LONG ( maxOverlap ),
FT_FRAME_END
};
static FT_Error
pcf_get_accel( FT_Stream stream,
PCF_Face face,
FT_ULong type )
{
FT_ULong format, size;
FT_Error error = PCF_Err_Ok;
PCF_Accel accel = &face->accel;
error = pcf_seek_to_table_type( stream,
face->toc.tables,
face->toc.count,
type,
&format,
&size );
if ( error )
goto Bail;
if ( FT_READ_ULONG_LE( format ) )
goto Bail;
if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) &&
!PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
goto Bail;
if ( PCF_BYTE_ORDER( format ) == MSBFirst )
{
if ( FT_STREAM_READ_FIELDS( pcf_accel_msb_header, accel ) )
goto Bail;
}
else
{
if ( FT_STREAM_READ_FIELDS( pcf_accel_header, accel ) )
goto Bail;
}
error = pcf_get_metric( stream,
format & ( ~PCF_FORMAT_MASK ),
&(accel->minbounds) );
if ( error )
goto Bail;
error = pcf_get_metric( stream,
format & ( ~PCF_FORMAT_MASK ),
&(accel->maxbounds) );
if ( error )
goto Bail;
if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
{
error = pcf_get_metric( stream,
format & ( ~PCF_FORMAT_MASK ),
&(accel->ink_minbounds) );
if ( error )
goto Bail;
error = pcf_get_metric( stream,
format & ( ~PCF_FORMAT_MASK ),
&(accel->ink_maxbounds) );
if ( error )
goto Bail;
}
else
{
accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
accel->ink_maxbounds = accel->maxbounds;
}
Bail:
return error;
}
static FT_Error
pcf_interpret_style( PCF_Face pcf )
{
FT_Error error = PCF_Err_Ok;
FT_Face face = FT_FACE( pcf );
FT_Memory memory = face->memory;
PCF_Property prop;
char *istr = NULL, *bstr = NULL;
char *sstr = NULL, *astr = NULL;
int parts = 0, len = 0;
face->style_flags = 0;
prop = pcf_find_property( pcf, "SLANT" );
if ( prop && prop->isString &&
( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
*(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) )
{
face->style_flags |= FT_STYLE_FLAG_ITALIC;
istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
? (char *)"Oblique"
: (char *)"Italic";
len += ft_strlen( istr );
parts++;
}
prop = pcf_find_property( pcf, "WEIGHT_NAME" );
if ( prop && prop->isString &&
( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
{
face->style_flags |= FT_STYLE_FLAG_BOLD;
bstr = (char *)"Bold";
len += ft_strlen( bstr );
parts++;
}
prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
if ( prop && prop->isString &&
*(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
{
sstr = (char *)(prop->value.atom);
len += ft_strlen( sstr );
parts++;
}
prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
if ( prop && prop->isString &&
*(prop->value.atom) &&
!( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
{
astr = (char *)(prop->value.atom);
len += ft_strlen( astr );
parts++;
}
if ( !parts || !len )
{
if ( FT_ALLOC( face->style_name, 8 ) )
return error;
ft_strcpy( face->style_name, "Regular" );
face->style_name[7] = '\0';
}
else
{
char *style, *s;
unsigned int i;
if ( FT_ALLOC( style, len + parts ) )
return error;
s = style;
if ( astr )
{
ft_strcpy( s, astr );
for ( i = 0; i < ft_strlen( astr ); i++, s++ )
if ( *s == ' ' )
*s = '-'; /* replace spaces with dashes */
*(s++) = ' ';
}
if ( bstr )
{
ft_strcpy( s, bstr );
s += ft_strlen( bstr );
*(s++) = ' ';
}
if ( istr )
{
ft_strcpy( s, istr );
s += ft_strlen( istr );
*(s++) = ' ';
}
if ( sstr )
{
ft_strcpy( s, sstr );
for ( i = 0; i < ft_strlen( sstr ); i++, s++ )
if ( *s == ' ' )
*s = '-'; /* replace spaces with dashes */
*(s++) = ' ';
}
*(--s) = '\0'; /* overwrite last ' ', terminate the string */
face->style_name = style; /* allocated string */
}
return error;
}
FT_LOCAL_DEF( FT_Error )
pcf_load_font( FT_Stream stream,
PCF_Face face )
{
FT_Error error = PCF_Err_Ok;
FT_Memory memory = FT_FACE(face)->memory;
FT_Bool hasBDFAccelerators;
error = pcf_read_TOC( stream, face );
if ( error )
goto Exit;
error = pcf_get_properties( stream, face );
if ( error )
goto Exit;
/* Use the old accelerators if no BDF accelerators are in the file. */
hasBDFAccelerators = pcf_has_table_type( face->toc.tables,
face->toc.count,
PCF_BDF_ACCELERATORS );
if ( !hasBDFAccelerators )
{
error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
if ( error )
goto Exit;
}
/* metrics */
error = pcf_get_metrics( stream, face );
if ( error )
goto Exit;
/* bitmaps */
error = pcf_get_bitmaps( stream, face );
if ( error )
goto Exit;
/* encodings */
error = pcf_get_encodings( stream, face );
if ( error )
goto Exit;
/* BDF style accelerators (i.e. bounds based on encoded glyphs) */
if ( hasBDFAccelerators )
{
error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
if ( error )
goto Exit;
}
/* XXX: TO DO: inkmetrics and glyph_names are missing */
/* now construct the face object */
{
FT_Face root = FT_FACE( face );
PCF_Property prop;
root->num_faces = 1;
root->face_index = 0;
root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
FT_FACE_FLAG_HORIZONTAL |
FT_FACE_FLAG_FAST_GLYPHS;
if ( face->accel.constantWidth )
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
if ( ( error = pcf_interpret_style( face ) ) != 0 )
goto Exit;
prop = pcf_find_property( face, "FAMILY_NAME" );
if ( prop && prop->isString )
{
int l = ft_strlen( prop->value.atom ) + 1;
if ( FT_NEW_ARRAY( root->family_name, l ) )
goto Exit;
ft_strcpy( root->family_name, prop->value.atom );
}
else
root->family_name = NULL;
/*
* Note: We shift all glyph indices by +1 since we must
* respect the convention that glyph 0 always corresponds
* to the `missing glyph'.
*
* This implies bumping the number of `available' glyphs by 1.
*/
root->num_glyphs = face->nmetrics + 1;
root->num_fixed_sizes = 1;
if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
goto Exit;
{
FT_Bitmap_Size* bsize = root->available_sizes;
FT_Short resolution_x = 0, resolution_y = 0;
FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) );
#if 0
bsize->height = face->accel.maxbounds.ascent << 6;
#endif
bsize->height = (FT_Short)( face->accel.fontAscent +
face->accel.fontDescent );
prop = pcf_find_property( face, "AVERAGE_WIDTH" );
if ( prop )
bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 );
else
bsize->width = (FT_Short)( bsize->height * 2/3 );
prop = pcf_find_property( face, "POINT_SIZE" );
if ( prop )
/* convert from 722.7 decipoints to 72 points per inch */
bsize->size =
(FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L );
prop = pcf_find_property( face, "PIXEL_SIZE" );
if ( prop )
bsize->y_ppem = (FT_Short)prop->value.integer << 6;
prop = pcf_find_property( face, "RESOLUTION_X" );
if ( prop )
resolution_x = (FT_Short)prop->value.integer;
prop = pcf_find_property( face, "RESOLUTION_Y" );
if ( prop )
resolution_y = (FT_Short)prop->value.integer;
if ( bsize->y_ppem == 0 )
{
bsize->y_ppem = bsize->size;
if ( resolution_y )
bsize->y_ppem = bsize->y_ppem * resolution_y / 72;
}
if ( resolution_x && resolution_y )
bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y;
else
bsize->x_ppem = bsize->y_ppem;
}
/* set up charset */
{
PCF_Property charset_registry = 0, charset_encoding = 0;
charset_registry = pcf_find_property( face, "CHARSET_REGISTRY" );
charset_encoding = pcf_find_property( face, "CHARSET_ENCODING" );
if ( charset_registry && charset_registry->isString &&
charset_encoding && charset_encoding->isString )
{
if ( FT_NEW_ARRAY( face->charset_encoding,
ft_strlen( charset_encoding->value.atom ) + 1 ) )
goto Exit;
if ( FT_NEW_ARRAY( face->charset_registry,
ft_strlen( charset_registry->value.atom ) + 1 ) )
goto Exit;
ft_strcpy( face->charset_registry, charset_registry->value.atom );
ft_strcpy( face->charset_encoding, charset_encoding->value.atom );
}
}
}
Exit:
if ( error )
{
/* This is done to respect the behaviour of the original */
/* PCF font driver. */
error = PCF_Err_Invalid_File_Format;
}
return error;
}
/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -