📄 cffload.c
字号:
if ( sid )
gid = cff_charset_cid_to_gindex( charset, sid );
if ( gid != 0 )
{
encoding->codes[j] = (FT_UShort)gid;
if ( encoding->count < j + 1 )
encoding->count = j + 1;
}
else
{
encoding->codes[j] = 0;
encoding->sids [j] = 0;
}
}
break;
default:
FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
}
Exit:
/* Clean up if there was an error. */
return error;
}
static FT_Error
cff_subfont_load( CFF_SubFont font,
CFF_Index idx,
FT_UInt font_index,
FT_Stream stream,
FT_ULong base_offset )
{
FT_Error error;
CFF_ParserRec parser;
FT_Byte* dict = NULL;
FT_ULong dict_len;
CFF_FontRecDict top = &font->font_dict;
CFF_Private priv = &font->private_dict;
cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );
/* set defaults */
FT_MEM_ZERO( top, sizeof ( *top ) );
top->underline_position = -100L << 16;
top->underline_thickness = 50L << 16;
top->charstring_type = 2;
top->font_matrix.xx = 0x10000L;
top->font_matrix.yy = 0x10000L;
top->cid_count = 8720;
/* we use the implementation specific SID value 0xFFFF to indicate */
/* missing entries */
top->version = 0xFFFFU;
top->notice = 0xFFFFU;
top->copyright = 0xFFFFU;
top->full_name = 0xFFFFU;
top->family_name = 0xFFFFU;
top->weight = 0xFFFFU;
top->embedded_postscript = 0xFFFFU;
top->cid_registry = 0xFFFFU;
top->cid_ordering = 0xFFFFU;
top->cid_font_name = 0xFFFFU;
error = cff_index_access_element( idx, font_index, &dict, &dict_len ) ||
cff_parser_run( &parser, dict, dict + dict_len );
cff_index_forget_element( idx, &dict );
if ( error )
goto Exit;
/* if it is a CID font, we stop there */
if ( top->cid_registry != 0xFFFFU )
goto Exit;
/* parse the private dictionary, if any */
if ( top->private_offset && top->private_size )
{
/* set defaults */
FT_MEM_ZERO( priv, sizeof ( *priv ) );
priv->blue_shift = 7;
priv->blue_fuzz = 1;
priv->lenIV = -1;
priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
FT_FRAME_ENTER( font->font_dict.private_size ) )
goto Exit;
error = cff_parser_run( &parser,
(FT_Byte*)stream->cursor,
(FT_Byte*)stream->limit );
FT_FRAME_EXIT();
if ( error )
goto Exit;
/* ensure that `num_blue_values' is even */
priv->num_blue_values &= ~1;
}
/* read the local subrs, if any */
if ( priv->local_subrs_offset )
{
if ( FT_STREAM_SEEK( base_offset + top->private_offset +
priv->local_subrs_offset ) )
goto Exit;
error = cff_index_init( &font->local_subrs_index, stream, 1 );
if ( error )
goto Exit;
font->num_local_subrs = font->local_subrs_index.count;
error = cff_index_get_pointers( &font->local_subrs_index,
&font->local_subrs );
if ( error )
goto Exit;
}
Exit:
return error;
}
static void
cff_subfont_done( FT_Memory memory,
CFF_SubFont subfont )
{
if ( subfont )
{
cff_index_done( &subfont->local_subrs_index );
FT_FREE( subfont->local_subrs );
}
}
FT_LOCAL_DEF( FT_Error )
cff_font_load( FT_Stream stream,
FT_Int face_index,
CFF_Font font )
{
static const FT_Frame_Field cff_header_fields[] =
{
#undef FT_STRUCTURE
#define FT_STRUCTURE CFF_FontRec
FT_FRAME_START( 4 ),
FT_FRAME_BYTE( version_major ),
FT_FRAME_BYTE( version_minor ),
FT_FRAME_BYTE( header_size ),
FT_FRAME_BYTE( absolute_offsize ),
FT_FRAME_END
};
FT_Error error;
FT_Memory memory = stream->memory;
FT_ULong base_offset;
CFF_FontRecDict dict;
FT_ZERO( font );
font->stream = stream;
font->memory = memory;
dict = &font->top_font.font_dict;
base_offset = FT_STREAM_POS();
/* read CFF font header */
if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
goto Exit;
/* check format */
if ( font->version_major != 1 ||
font->header_size < 4 ||
font->absolute_offsize > 4 )
{
FT_TRACE2(( "[not a CFF font header!]\n" ));
error = CFF_Err_Unknown_File_Format;
goto Exit;
}
/* skip the rest of the header */
if ( FT_STREAM_SKIP( font->header_size - 4 ) )
goto Exit;
/* read the name, top dict, string and global subrs index */
if ( FT_SET_ERROR( cff_index_init( &font->name_index,
stream, 0 ) ) ||
FT_SET_ERROR( cff_index_init( &font->font_dict_index,
stream, 0 ) ) ||
FT_SET_ERROR( cff_index_init( &font->string_index,
stream, 0 ) ) ||
FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
stream, 1 ) ) )
goto Exit;
/* well, we don't really forget the `disabled' fonts... */
font->num_faces = font->name_index.count;
if ( face_index >= (FT_Int)font->num_faces )
{
FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
face_index ));
error = CFF_Err_Invalid_Argument;
}
/* in case of a font format check, simply exit now */
if ( face_index < 0 )
goto Exit;
/* now, parse the top-level font dictionary */
error = cff_subfont_load( &font->top_font,
&font->font_dict_index,
face_index,
stream,
base_offset );
if ( error )
goto Exit;
if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
goto Exit;
error = cff_index_init( &font->charstrings_index, stream, 0 );
if ( error )
goto Exit;
/* now, check for a CID font */
if ( dict->cid_registry != 0xFFFFU )
{
CFF_IndexRec fd_index;
CFF_SubFont sub;
FT_UInt idx;
/* this is a CID-keyed font, we must now allocate a table of */
/* sub-fonts, then load each of them separately */
if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
goto Exit;
error = cff_index_init( &fd_index, stream, 0 );
if ( error )
goto Exit;
if ( fd_index.count > CFF_MAX_CID_FONTS )
{
FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
goto Fail_CID;
}
/* allocate & read each font dict independently */
font->num_subfonts = fd_index.count;
if ( FT_NEW_ARRAY( sub, fd_index.count ) )
goto Fail_CID;
/* set up pointer table */
for ( idx = 0; idx < fd_index.count; idx++ )
font->subfonts[idx] = sub + idx;
/* now load each subfont independently */
for ( idx = 0; idx < fd_index.count; idx++ )
{
sub = font->subfonts[idx];
error = cff_subfont_load( sub, &fd_index, idx,
stream, base_offset );
if ( error )
goto Fail_CID;
}
/* now load the FD Select array */
error = CFF_Load_FD_Select( &font->fd_select,
font->charstrings_index.count,
stream,
base_offset + dict->cid_fd_select_offset );
Fail_CID:
cff_index_done( &fd_index );
if ( error )
goto Exit;
}
else
font->num_subfonts = 0;
/* read the charstrings index now */
if ( dict->charstrings_offset == 0 )
{
FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
error = CFF_Err_Unknown_File_Format;
goto Exit;
}
/* explicit the global subrs */
font->num_global_subrs = font->global_subrs_index.count;
font->num_glyphs = font->charstrings_index.count;
error = cff_index_get_pointers( &font->global_subrs_index,
&font->global_subrs ) ;
if ( error )
goto Exit;
/* read the Charset and Encoding tables if available */
if ( font->num_glyphs > 0 )
{
FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU );
error = cff_charset_load( &font->charset, font->num_glyphs, stream,
base_offset, dict->charset_offset, invert );
if ( error )
goto Exit;
/* CID-keyed CFFs don't have an encoding */
if ( dict->cid_registry == 0xFFFFU )
{
error = cff_encoding_load( &font->encoding,
&font->charset,
font->num_glyphs,
stream,
base_offset,
dict->encoding_offset );
if ( error )
goto Exit;
}
else
/* CID-keyed fonts only need CIDs */
FT_FREE( font->charset.sids );
}
/* get the font name (/CIDFontName for CID-keyed fonts, */
/* /FontName otherwise) */
font->font_name = cff_index_get_name( &font->name_index, face_index );
Exit:
return error;
}
FT_LOCAL_DEF( void )
cff_font_done( CFF_Font font )
{
FT_Memory memory = font->memory;
FT_UInt idx;
cff_index_done( &font->global_subrs_index );
cff_index_done( &font->string_index );
cff_index_done( &font->font_dict_index );
cff_index_done( &font->name_index );
cff_index_done( &font->charstrings_index );
/* release font dictionaries, but only if working with */
/* a CID keyed CFF font */
if ( font->num_subfonts > 0 )
{
for ( idx = 0; idx < font->num_subfonts; idx++ )
cff_subfont_done( memory, font->subfonts[idx] );
/* the subfonts array has been allocated as a single block */
FT_FREE( font->subfonts[0] );
}
cff_encoding_done( &font->encoding );
cff_charset_done( &font->charset, font->stream );
cff_subfont_done( memory, &font->top_font );
CFF_Done_FD_Select( &font->fd_select, font->stream );
if (font->font_info != NULL)
{
FT_FREE( font->font_info->version );
FT_FREE( font->font_info->notice );
FT_FREE( font->font_info->full_name );
FT_FREE( font->font_info->family_name );
FT_FREE( font->font_info->weight );
FT_FREE( font->font_info );
}
FT_FREE( font->global_subrs );
FT_FREE( font->font_name );
}
/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -