?? cffload.c
字號:
goto Exit;
}
/* Zero out the code to gid/sid mappings. */
for ( j = 0; j < 256; j++ )
{
encoding->sids [j] = 0;
encoding->codes[j] = 0;
}
/* Note: The encoding table in a CFF font is indexed by glyph index; */
/* the first encoded glyph index is 1. Hence, we read the character */
/* code (`glyph_code') at index j and make the assignment: */
/* */
/* encoding->codes[glyph_code] = j + 1 */
/* */
/* We also make the assignment: */
/* */
/* encoding->sids[glyph_code] = charset->sids[j + 1] */
/* */
/* This gives us both a code to GID and a code to SID mapping. */
if ( offset > 1 )
{
encoding->offset = base_offset + offset;
/* we need to parse the table to determine its size */
if ( FT_STREAM_SEEK( encoding->offset ) ||
FT_READ_BYTE( encoding->format ) ||
FT_READ_BYTE( count ) )
goto Exit;
switch ( encoding->format & 0x7F )
{
case 0:
{
FT_Byte* p;
/* By convention, GID 0 is always ".notdef" and is never */
/* coded in the font. Hence, the number of codes found */
/* in the table is `count+1'. */
/* */
encoding->count = count + 1;
if ( FT_FRAME_ENTER( count ) )
goto Exit;
p = (FT_Byte*)stream->cursor;
for ( j = 1; j <= count; j++ )
{
glyph_code = *p++;
/* Make sure j is not too big. */
if ( j < num_glyphs )
{
/* Assign code to GID mapping. */
encoding->codes[glyph_code] = (FT_UShort)j;
/* Assign code to SID mapping. */
encoding->sids[glyph_code] = charset->sids[j];
}
}
FT_FRAME_EXIT();
}
break;
case 1:
{
FT_UInt nleft;
FT_UInt i = 1;
FT_UInt k;
encoding->count = 0;
/* Parse the Format1 ranges. */
for ( j = 0; j < count; j++, i += nleft )
{
/* Read the first glyph code of the range. */
if ( FT_READ_BYTE( glyph_code ) )
goto Exit;
/* Read the number of codes in the range. */
if ( FT_READ_BYTE( nleft ) )
goto Exit;
/* Increment nleft, so we read `nleft + 1' codes/sids. */
nleft++;
/* compute max number of character codes */
if ( (FT_UInt)nleft > encoding->count )
encoding->count = nleft;
/* Fill in the range of codes/sids. */
for ( k = i; k < nleft + i; k++, glyph_code++ )
{
/* Make sure k is not too big. */
if ( k < num_glyphs && glyph_code < 256 )
{
/* Assign code to GID mapping. */
encoding->codes[glyph_code] = (FT_UShort)k;
/* Assign code to SID mapping. */
encoding->sids[glyph_code] = charset->sids[k];
}
}
}
/* simple check; one never knows what can be found in a font */
if ( encoding->count > 256 )
encoding->count = 256;
}
break;
default:
FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
error = CFF_Err_Invalid_File_Format;
goto Exit;
}
/* Parse supplemental encodings, if any. */
if ( encoding->format & 0x80 )
{
FT_UInt gindex;
/* count supplements */
if ( FT_READ_BYTE( count ) )
goto Exit;
for ( j = 0; j < count; j++ )
{
/* Read supplemental glyph code. */
if ( FT_READ_BYTE( glyph_code ) )
goto Exit;
/* Read the SID associated with this glyph code. */
if ( FT_READ_USHORT( glyph_sid ) )
goto Exit;
/* Assign code to SID mapping. */
encoding->sids[glyph_code] = glyph_sid;
/* First, look up GID which has been assigned to */
/* SID glyph_sid. */
for ( gindex = 0; gindex < num_glyphs; gindex++ )
{
if ( charset->sids[gindex] == glyph_sid )
{
encoding->codes[glyph_code] = (FT_UShort)gindex;
break;
}
}
}
}
}
else
{
FT_UInt i;
/* We take into account the fact a CFF font can use a predefined */
/* encoding without containing all of the glyphs encoded by this */
/* encoding (see the note at the end of section 12 in the CFF */
/* specification). */
switch ( (FT_UInt)offset )
{
case 0:
/* First, copy the code to SID mapping. */
FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
goto Populate;
case 1:
/* First, copy the code to SID mapping. */
FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
Populate:
/* Construct code to GID mapping from code to SID mapping */
/* and charset. */
encoding->count = 0;
for ( j = 0; j < 256; j++ )
{
/* If j is encoded, find the GID for it. */
if ( encoding->sids[j] )
{
for ( i = 1; i < num_glyphs; i++ )
/* We matched, so break. */
if ( charset->sids[i] == encoding->sids[j] )
break;
/* i will be equal to num_glyphs if we exited the above */
/* loop without a match. In this case, we also have to */
/* fix the code to SID mapping. */
if ( i == num_glyphs )
{
encoding->codes[j] = 0;
encoding->sids [j] = 0;
}
else
{
encoding->codes[j] = (FT_UShort)i;
/* update encoding count */
if ( encoding->count < j + 1 )
encoding->count = j + 1;
}
}
}
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_new_index( &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_done_index( &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_new_index( &font->name_index, stream, 0 )) ||
FT_SET_ERROR( cff_new_index( &font->font_dict_index, stream, 0 )) ||
FT_SET_ERROR( cff_new_index( &font->string_index, stream, 0 )) ||
FT_SET_ERROR( cff_new_index( &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_new_index( &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_new_index( &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_done_index( &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_done_index( &font->global_subrs_index );
cff_done_index( &font->string_index );
cff_done_index( &font->font_dict_index );
cff_done_index( &font->name_index );
cff_done_index( &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] );
}
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 );
FT_FREE( font->global_subrs );
FT_FREE( font->font_name );
}
/* END */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -