From 3fd12f1478c8a3f5ee235238c824c57fb19fc375 Mon Sep 17 00:00:00 2001 From: Graham Asher Date: Thu, 15 Aug 2002 12:10:48 +0000 Subject: [PATCH] Implemented incremental loading for the CFF driver. --- src/cff/cffgload.c | 98 ++++++++++++++++++++++++++++++++++++++-------- src/cff/cffload.c | 59 ++++++++++++++++------------ src/cff/cffload.h | 3 +- src/cff/cffobjs.c | 2 +- 4 files changed, 120 insertions(+), 42 deletions(-) diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index 6e86db657..a86f2185c 100644 --- a/src/cff/cffgload.c +++ b/src/cff/cffgload.c @@ -560,6 +560,62 @@ } + static FT_Error + cff_get_glyph_data( TT_Face face, + FT_UInt glyph_index, + FT_Byte** pointer, + FT_ULong* length ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + FT_Error error = face->root.internal->incremental_interface->funcs->get_glyph_data( + face->root.internal->incremental_interface->object, + glyph_index, &data ); + *pointer = (FT_Byte*)data.pointer; + *length = data.length; + return error; + } + else +#endif + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + return cff_index_access_element( &cff->charstrings_index, glyph_index, + pointer, length ); + } + } + + + static void + cff_free_glyph_data( TT_Face face, + FT_Byte** pointer, + FT_ULong length ) + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( face->root.internal->incremental_interface ) + { + FT_Data data; + data.pointer = *pointer; + data.length = length; + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object,&data ); + } + else +#endif + + { + CFF_Font cff = (CFF_Font)(face->extra.data); + cff_index_forget_element( &cff->charstrings_index, pointer ); + } + } + + static FT_Error cff_operator_seac( CFF_Decoder* decoder, FT_Pos adx, @@ -626,8 +682,8 @@ } /* First load `bchar' in builder */ - error = cff_index_access_element( &cff->charstrings_index, bchar_index, - &charstring, &charstring_len ); + error = cff_get_glyph_data( face, bchar_index, + &charstring, &charstring_len ); if ( !error ) { error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); @@ -635,7 +691,7 @@ if ( error ) goto Exit; - cff_index_forget_element( &cff->charstrings_index, &charstring ); + cff_free_glyph_data( face, &charstring, charstring_len ); } n_base_points = base->n_points; @@ -650,8 +706,8 @@ decoder->builder.left_bearing.y = 0; /* Now load `achar' on top of the base outline. */ - error = cff_index_access_element( &cff->charstrings_index, achar_index, - &charstring, &charstring_len ); + error = cff_get_glyph_data( face, achar_index, + &charstring, &charstring_len ); if ( !error ) { error = cff_decoder_parse_charstrings( decoder, charstring, charstring_len ); @@ -659,7 +715,7 @@ if ( error ) goto Exit; - cff_index_forget_element( &cff->charstrings_index, &charstring ); + cff_free_glyph_data( face, &charstring, charstring_len ); } /* Restore the left side bearing and advance width */ @@ -2144,15 +2200,15 @@ /* now get load the unscaled outline */ - error = cff_index_access_element( &cff->charstrings_index, glyph_index, - &charstring, &charstring_len ); + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); if ( !error ) { cff_decoder_prepare( &decoder, glyph_index ); error = cff_decoder_parse_charstrings( &decoder, charstring, charstring_len ); - cff_index_forget_element( &cff->charstrings_index, &charstring ); + cff_free_glyph_data( face, &charstring, &charstring_len ); } /* ignore the error if one has occurred -- skip to next glyph */ @@ -2230,27 +2286,37 @@ (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ); /* now load the unscaled outline */ - error = cff_index_access_element( &cff->charstrings_index, glyph_index, - &charstring, &charstring_len ); + error = cff_get_glyph_data( face, glyph_index, + &charstring, &charstring_len ); if ( !error ) { - CFF_IndexRec csindex = cff->charstrings_index; - - cff_decoder_prepare( &decoder, glyph_index ); error = cff_decoder_parse_charstrings( &decoder, charstring, charstring_len ); - cff_index_forget_element( &cff->charstrings_index, &charstring ); + cff_free_glyph_data( face, &charstring, charstring_len ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Control data and length may not be available for incremental */ + /* fonts. */ + if ( face->root.internal->incremental_interface ) + { + glyph->root.control_data = 0; + glyph->root.control_len = 0; + } + else +#endif /* We set control_data and control_len if charstrings is loaded. */ /* See how charstring loads at cff_index_access_element() in */ /* cffload.c. */ - + { + CFF_IndexRec csindex = cff->charstrings_index; glyph->root.control_data = csindex.bytes + csindex.offsets[glyph_index] - 1; glyph->root.control_len = charstring_len; + } } /* save new glyph tables */ diff --git a/src/cff/cffload.c b/src/cff/cffload.c index 2829ffcb4..9193d8e7b 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -2027,7 +2027,8 @@ FT_LOCAL_DEF( FT_Error ) cff_font_load( FT_Stream stream, FT_Int face_index, - CFF_Font font ) + CFF_Font font, + CFF_Face face ) { static const FT_Frame_Field cff_header_fields[] = { @@ -2159,20 +2160,27 @@ 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; - } +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't need character recipes. */ + if (!face->root.internal->incremental_interface) +#endif + { - if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) - goto Exit; + /* 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; + } - error = cff_new_index( &font->charstrings_index, stream, 0 ); - 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; + } /* explicit the global subrs */ font->num_global_subrs = font->global_subrs_index.count; @@ -2185,19 +2193,22 @@ goto Exit; /* read the Charset and Encoding tables when available */ - error = cff_charset_load( &font->charset, font->num_glyphs, stream, + if ( font->num_glyphs > 0 ) + { + error = cff_charset_load( &font->charset, font->num_glyphs, stream, base_offset, dict->charset_offset ); - if ( error ) - goto Exit; + if ( error ) + goto Exit; - error = cff_encoding_load( &font->encoding, - &font->charset, - font->num_glyphs, - stream, - base_offset, - dict->encoding_offset ); - if ( error ) - goto Exit; + error = cff_encoding_load( &font->encoding, + &font->charset, + font->num_glyphs, + stream, + base_offset, + dict->encoding_offset ); + if ( error ) + goto Exit; + } /* get the font name */ font->font_name = cff_index_get_name( &font->name_index, face_index ); diff --git a/src/cff/cffload.h b/src/cff/cffload.h index 4cadfe6bb..3051a2502 100644 --- a/src/cff/cffload.h +++ b/src/cff/cffload.h @@ -55,7 +55,8 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) cff_font_load( FT_Stream stream, FT_Int face_index, - CFF_Font font ); + CFF_Font font, + CFF_Face face ); FT_LOCAL( void ) cff_font_done( CFF_Font font ); diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index a1b6166c3..3dead514a 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -342,7 +342,7 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( stream, face_index, cff ); + error = cff_font_load( stream, face_index, cff, face ); if ( error ) goto Exit;