Commit 3fd12f1478c8a3f5ee235238c824c57fb19fc375

Graham Asher 2002-08-15T12:10:48

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