Commit 55127272c4d67e662e18805917601fe56df8f83f

Werner Lemberg 2012-11-13T09:22:11

[cff] Add support for OpenType Collections (OTC). * src/cff/cffload.c (cff_font_load): Separate subfont and face index handling to load both pure CFFs with multiple subfonts and OTCs (with multiple faces where each face holds exactly one subfont). * src/cff/cffobjs.c (cff_face_init): Updated.

diff --git a/ChangeLog b/ChangeLog
index 98ef669..a7b17f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-11-13  Werner Lemberg  <wl@gnu.org>
+
+	[cff] Add support for OpenType Collections (OTC).
+
+	* src/cff/cffload.c (cff_font_load): Separate subfont and face
+	index handling to load both pure CFFs with multiple subfonts and
+	OTCs (with multiple faces where each face holds exactly one
+	subfont).
+	* src/cff/cffobjs.c (cff_face_init): Updated.
+
 2012-11-12  Werner Lemberg  <wl@gnu.org>
 
 	[autofit] Minor improvement.
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 2be6ba0..d5433c8 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType and CFF data/program tables loader (body).                  */
 /*                                                                         */
-/*  Copyright 1996-2011 by                                                 */
+/*  Copyright 1996-2012 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1439,6 +1439,7 @@
     FT_ULong         base_offset;
     CFF_FontRecDict  dict;
     CFF_IndexRec     string_index;
+    FT_Int           subfont_index;
 
 
     FT_ZERO( font );
@@ -1483,13 +1484,35 @@
 
     font->num_strings = string_index.count;
 
-    /* well, we don't really forget the `disabled' fonts... */
-    font->num_faces = font->name_index.count;
-    if ( face_index >= (FT_Int)font->num_faces )
+    if ( pure_cff )
     {
-      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
-                 face_index ));
-      error = CFF_Err_Invalid_Argument;
+      /* well, we don't really forget the `disabled' fonts... */
+      subfont_index = face_index;
+
+      if ( subfont_index >= (FT_Int)font->name_index.count )
+      {
+        FT_ERROR(( "cff_font_load:"
+                   " invalid subfont index for pure CFF font (%d)\n",
+                   subfont_index ));
+        error = CFF_Err_Invalid_Argument;
+        goto Exit;
+      }
+
+      font->num_faces = font->name_index.count;
+    }
+    else
+    {
+      subfont_index = 0;
+
+      if ( font->name_index.count > 1 )
+      {
+        FT_ERROR(( "cff_font_load:"
+                   " invalid CFF font with multiple subfonts\n"
+                   "              "
+                   " in SFNT wrapper\n" ));
+        error = CFF_Err_Invalid_File_Format;
+        goto Exit;
+      }
     }
 
     /* in case of a font format check, simply exit now */
@@ -1500,7 +1523,7 @@
     FT_TRACE4(( "parsing top-level\n" ));
     error = cff_subfont_load( &font->top_font,
                               &font->font_dict_index,
-                              face_index,
+                              subfont_index,
                               stream,
                               base_offset,
                               library );
@@ -1615,7 +1638,7 @@
 
     /* get the font name (/CIDFontName for CID-keyed fonts, */
     /* /FontName otherwise)                                 */
-    font->font_name = cff_index_get_name( font, face_index );
+    font->font_name = cff_index_get_name( font, subfont_index );
 
   Exit:
     cff_index_done( &string_index );
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index aa3e9d3..b4dddb7 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -526,14 +526,6 @@
       if ( face_index < 0 )
         return CFF_Err_Ok;
 
-      /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */
-      if ( face_index > 0 )
-      {
-        FT_ERROR(( "cff_face_init: invalid face index\n" ));
-        error = CFF_Err_Invalid_Argument;
-        goto Exit;
-      }
-
       sfnt_format = 1;
 
       /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
@@ -544,7 +536,8 @@
         pure_cff = 0;
 
         /* load font directory */
-        error = sfnt->load_face( stream, face, 0, num_params, params );
+        error = sfnt->load_face( stream, face, face_index,
+                                 num_params, params );
         if ( error )
           goto Exit;
       }
@@ -554,10 +547,6 @@
         error = sfnt->load_cmap( face, stream );
         if ( error )
           goto Exit;
-
-        /* XXX: we don't load the GPOS table, as OpenType Layout     */
-        /* support will be added later to a layout library on top of */
-        /* FreeType 2                                                */
       }
 
       /* now load the CFF part of the file */