📄 cffload.c
字号:
/* 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 { /* 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; error = cff_charset_compute_cids( charset, num_glyphs, stream->memory ); if ( error ) goto Exit; for ( j = 0; j < 256; j++ ) { FT_UInt sid = encoding->sids[j]; FT_UInt gid = 0; 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 + -