Commit ea94abb1851fcff553af724e7e31e4844b3adec6

Graham Asher 2002-07-18T16:25:57

Added the incremental loading system for the CID driver. Tested using my own unit test code.

diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index 3c0a898..78088e0 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -43,75 +43,112 @@
     CID_Face      face = (CID_Face)decoder->builder.face;
     CID_FaceInfo  cid  = &face->cid;
     FT_Byte*      p;
-    FT_UInt       entry_len = cid->fd_bytes + cid->gd_bytes;
     FT_UInt       fd_select;
-    FT_ULong      off1, glyph_len;
     FT_Stream     stream = face->root.stream;
     FT_Error      error  = 0;
+    FT_Byte*      charstring = 0;
+	FT_Memory     memory = face->root.memory;
+    FT_UInt       glyph_length = 0;
 
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+	/* For incremental fonts get the character data using the callback function. */
+    if (face->root.incremental_interface)
+    {
+      FT_Data glyph_data;
+      error = face->root.incremental_interface->funcs->get_glyph_data(face->root.incremental_interface->object,
+        glyph_index,&glyph_data);
+      if (error)
+        goto Exit;
+      p = (FT_Byte*)glyph_data.pointer;
+      fd_select = (FT_UInt)cid_get_offset(&p,(FT_Byte)cid->fd_bytes);
+      glyph_data.pointer += cid->fd_bytes;
+      glyph_data.length -= cid->fd_bytes;
+      glyph_length = glyph_data.length;
+
+      if (glyph_length == 0)
+        goto Exit;
+      if (FT_ALLOC(charstring,glyph_length))
+        goto Exit;
+      ft_memcpy(charstring,glyph_data.pointer,glyph_length);
+    }
+else
+#endif
 
-    /* read the CID font dict index and charstring offset from the CIDMap */
-    if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
-                         glyph_index * entry_len )               ||
-         FT_FRAME_ENTER( 2 * entry_len )                         )
-      goto Exit;
+    /* For ordinary fonts read the CID font dictionary index and charstring offset from the CIDMap. */
+    {
+      FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
+      FT_ULong off1;
+      if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
+           glyph_index * entry_len ) ||
+           FT_FRAME_ENTER( 2 * entry_len ) )
+        goto Exit;
 
-    p = (FT_Byte*)stream->cursor;
-    fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
-    off1      = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
-    p        += cid->fd_bytes;
-    glyph_len = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
+      p = (FT_Byte*)stream->cursor;
+      fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
+      off1      = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
+      p        += cid->fd_bytes;
+      glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
+      FT_FRAME_EXIT();
 
-    FT_FRAME_EXIT();
+      if (glyph_length == 0)
+        goto Exit;
+      if (FT_ALLOC(charstring,glyph_length))
+        goto Exit;
+      if (FT_STREAM_READ_AT(cid->data_offset + off1,charstring,glyph_length))
+        goto Exit;
+    }
 
-    /* now, if the glyph is not empty, set up the subrs array, and parse */
-    /* the charstrings                                                   */
-    if ( glyph_len > 0 )
+    /* Now set up the subrs array and parse the charstrings. */
     {
       CID_FaceDict  dict;
       CID_Subrs     cid_subrs = face->subrs + fd_select;
-      FT_Byte*      charstring;
-      FT_Memory     memory = face->root.memory;
-
+	  FT_Int  cs_offset;
 
-      /* setup subrs */
+      /* Set up subrs */
       decoder->num_subrs = cid_subrs->num_subrs;
       decoder->subrs     = cid_subrs->code;
       decoder->subrs_len = 0;
 
-      /* setup font matrix */
+      /* Set up font matrix */
       dict                 = cid->font_dicts + fd_select;
 
       decoder->font_matrix = dict->font_matrix;
       decoder->font_offset = dict->font_offset;
       decoder->lenIV       = dict->private_dict.lenIV;
 
-      /* the charstrings are encoded (stupid!)  */
-      /* load the charstrings, then execute it  */
-
-      if ( FT_ALLOC( charstring, glyph_len ) )
-        goto Exit;
+	  /* Decode the charstring. */
 
-      if ( !FT_STREAM_READ_AT( cid->data_offset + off1,
-                               charstring, glyph_len ) )
-      {
-        FT_Int  cs_offset;
+      /* Adjustment for seed bytes. */
+      cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
 
+      /* Decrypt only if lenIV >= 0. */
+      if ( decoder->lenIV >= 0 )
+        cid_decrypt( charstring, glyph_length, 4330 );
 
-        /* Adjustment for seed bytes. */
-        cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
+      error = decoder->funcs.parse_charstrings( decoder,
+                                                charstring + cs_offset,
+                                                glyph_length  - cs_offset  );
+      }
 
-        /* Decrypt only if lenIV >= 0. */
-        if ( decoder->lenIV >= 0 )
-          cid_decrypt( charstring, glyph_len, 4330 );
+    FT_FREE( charstring );
 
-        error = decoder->funcs.parse_charstrings( decoder,
-                                                  charstring + cs_offset,
-                                                  glyph_len  - cs_offset  );
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    /* Incremental fonts can optionally override the metrics. */
+    if (!error && face->root.incremental_interface && face->root.incremental_interface->funcs->get_glyph_metrics)
+    {
+      FT_Bool found = FALSE;
+      FT_Basic_Glyph_Metrics metrics;
+      error = face->root.incremental_interface->funcs->get_glyph_metrics(face->root.incremental_interface->object,
+        glyph_index,FALSE,&metrics,&found);
+      if (found)
+      {
+        decoder->builder.left_bearing.x = metrics.bearing_x;
+        decoder->builder.left_bearing.y = metrics.bearing_y;
+        decoder->builder.advance.x = metrics.advance;
+        decoder->builder.advance.y = 0;
       }
-
-      FT_FREE( charstring );
     }
+#endif
 
   Exit:
     return error;