Implemented incremental loading for the CFF driver.
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 6e86db6..a86f218 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -561,6 +561,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,
FT_Pos ady,
@@ -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 2829ffc..9193d8e 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 4cadfe6..3051a25 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -55,7 +55,8 @@
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 a1b6166..3dead51 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;