Implemented incremental loading for the CFF driver.

This commit is contained in:
Graham Asher 2002-08-15 12:10:48 +00:00
parent cbfc97910e
commit 40a72ccbf3
4 changed files with 120 additions and 42 deletions

View File

@ -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 */

View File

@ -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 );

View File

@ -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 );

View File

@ -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;