Commit 53be6e9b1bca447fdb3d347ba3331eeaffe5aae1

Suzuki, Toshiya (鈴木俊哉) 2005-12-23T12:22:46

ftmac.c counts supported faces only

diff --git a/ChangeLog b/ChangeLog
index 6bdc065..c60cae8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2005-12-23  suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
+
+	* src/base/ftmac.c (FT_New_Face_From_Suitcase): Counts scalable
+	faces in supported formats (sfnt, LWFN) only, and ignore bitmap
+	faces in unsupported formats (fbit, NFNT). The number of available
+	faces are passed via face->num_faces. When bitmap faces are embedded
+	in sfnt resource, face->num_fixed_size is correctly set. In public
+	API, FT_New_Face() and FT_New_Face_From_FSSpec() count the faces
+	as FT_GetFile_From_Mac_Name(), which ignores NFNT resources.
+
+	* doc/CHANGES: Mention the changes.
+
 2005-12-17  Chia-I Wu  <b90201047@ntu.edu.tw>
 
 	* src/truetype/ttinterp.c (Update_Max): Set current size of buffer
diff --git a/docs/CHANGES b/docs/CHANGES
index 092387f..382c6b5 100644
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -43,6 +43,11 @@ LATEST CHANGES BETWEEN 2.2.0 and 2.1.10
 
   III. MISCELLANEOUS
 
+    - FT_New_Face() & FT_New_Face_From_FSSpec() in ftmac.c are changed
+      to count supported scalable faces (sfnt, LWFN) only, and returns
+      the number of available faces via face->num_faces.   Unsupported
+      bitmap faces (fbit, NFNT) are ignored.
+
     - SFNT cmap handling has been improved, mainly to run faster.
 
     - A new  face flag `FT_FACE_FLAG_HINTER'  has been added  which is
diff --git a/src/base/ftmac.c b/src/base/ftmac.c
index 5c06439..7a0599c 100644
--- a/src/base/ftmac.c
+++ b/src/base/ftmac.c
@@ -23,15 +23,11 @@
     support this I use the face_index argument of FT_(Open|New)_Face()
     functions, and pretend the suitcase file is a collection.
 
-    Warning: Although the FOND driver sets face->num_faces field to the
-    number of available fonts, but the Type 1 driver sets it to 1 anyway.
-    So this field is currently not reliable, and I don't see a clean way
-    to  resolve that.  The face_index argument translates to
-
-      Get1IndResource( 'FOND', face_index + 1 );
-
-    so clients should figure out the resource index of the FOND.
-    (I'll try to provide some example code for this at some point.)
+    Warning: fbit and NFNT bitmap resources are not supported yet.
+    In old sfnt fonts, bitmap glyph data for each sizes are stored in
+    each NFNT resources, instead of bdat table in sfnt resource.
+    Therefore, face->num_fixed_sizes is set to 0, because bitmap
+    data in NFNT resource is unavailable at present.
 
     The Mac FOND support works roughly like this:
 
@@ -267,6 +263,8 @@
   }
 
 
+  /* count_faces_sfnt() counts both of sfnt & NFNT refered by FOND */
+  /* count_faces_scalable() counts sfnt only refered by FOND       */
   static short
   count_faces_sfnt( char *fond_data )
   {
@@ -277,6 +275,28 @@
   }
 
 
+  static short
+  count_faces_scalable( char *fond_data )
+  {
+    AsscEntry*  assoc;
+    FamRec*     fond;
+    short       i, face, face_all;
+
+
+    fond       = (FamRec*)fond_data;
+    face_all   = *( (short *)( fond_data + sizeof ( FamRec ) ) ) + 1;
+    assoc      = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
+    face       = 0;
+
+    for ( i = 0; i < face_all; i++ )
+    {
+      if ( 0 == assoc[i].fontSize )
+        face ++;
+    }
+    return face;
+  }
+
+
   /* Look inside the FOND data, answer whether there should be an SFNT
      resource, and answer the name of a possible LWFN Type 1 file.
 
@@ -411,7 +431,7 @@
     if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
       return 1;
     else
-      return count_faces_sfnt( *fond );
+      return count_faces_scalable( *fond );
   }
 
 
@@ -744,36 +764,33 @@
                              FT_Long     face_index,
                              FT_Face    *aface )
   {
-    FT_Error  error = FT_Err_Ok;
+    FT_Error  error = FT_Err_Cannot_Open_Resource;
     short     res_index;
     Handle    fond;
-    short     num_faces;
+    short     num_faces_in_res, num_faces_in_fond;
 
 
     UseResFile( res_ref );
 
+    num_faces_in_res = 0;
     for ( res_index = 1; ; ++res_index )
     {
       fond = Get1IndResource( 'FOND', res_index );
       if ( ResError() )
-      {
-        error = FT_Err_Cannot_Open_Resource;
-        goto Error;
-      }
-      if ( face_index < 0 )
         break;
 
-      num_faces = count_faces( fond );
-      if ( face_index < num_faces )
-        break;
+      num_faces_in_fond  = count_faces( fond );
+      num_faces_in_res  += num_faces_in_fond;
 
-      face_index -= num_faces;
+      if ( 0 <= face_index && face_index < num_faces_in_fond && error )
+        error = FT_New_Face_From_FOND( library, fond, face_index, aface );
+      
+      face_index -= num_faces_in_fond;
     }
 
-    error = FT_New_Face_From_FOND( library, fond, face_index, aface );
-
-  Error:
     CloseResFile( res_ref );
+    if ( FT_Err_Ok == error && NULL != aface )
+      (*aface)->num_faces = num_faces_in_res;
     return error;
   }