freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft-devel] Improve(?) the face counting of suitcase font


From: mpsuzuki
Subject: [ft-devel] Improve(?) the face counting of suitcase font
Date: Wed, 5 Mar 2008 18:49:23 +0900

Hi all,

After the discussion with Deron Kazmaier about
the issue that FreeType2 is crashed by a suitcase
FOND referring inexisting sfnt resource, and
I understand the problem and background scenario.

For the people unfamiliar with suitcase font,
I explain the scenario by the analogy of TTC.
Please think about a broken TrueType collection:
the TTC header includes the number of included faces,
and the array of offsets to each faces. In the array
of offsets, there is an invalid offset pointing to
wrong position in the file, or to out of the file.
FreeType2 does not crawl all faces declared in TTC
header and does not check the face availability.
FreeType2 returns raw declared number of faces.
If a client tries to open the face whose offset is
invalid, it receives an error. I think this is most
simple and easy-to-understand implementation.

The current FT2 handling of invalid reference in Mac
suitcase font is similar. In the case of Mac suitcase
font, there is a map of "sfnt id" to the file offset,
and another map from face-name to "sfnt id". It is
possible that the 2nd map refers inexisting "sfnt id"
missing in the 1st map. The previous FreeType2 (before
2008-Feb-21) was crashed when a client requests
to open such invalid face in Mac suitcase font.
The current FreeType2 returns the error safely, but
the number of faces is still including invalid faces,
as the case of TTC.

It seems that current Mac OS X applications (e.g. FontBook
and its validator) silently ignores invalid sfnt id
in FOND and reduces the number of available faces,
so it's different from current FreeType2. I note classic
Mac OS recognizes invalid sfnt id as available one (and
fallback to unexpectedly-different font when it's requested).

I wrote a patch to simulate the face counting of suitcase
font in Mac OS X. By this patch, in each FT_Open_Face(),
FreeType2 crawls all sfnt ids and check their availability
(it does not check the internal of sfnt resource, just check
 the availability). I was afraid that such extra check
causes serious slow down, but it was not so serious.
I executed a small benchmark

        $ time find ./292suitcasefont-dir -type f -exec ftdump \{\} \;

on my old iBook (Mac OS X 10.4, PowerPC G3 600MHz, RAM 640MB)
and checked the time consumed. There is small slowdown
but not so serious, I think.

original (CVS HEAD)
-------------------
        real    1m58.274s
        user    0m33.537s
        sys     0m56.857s

patched to simulate Mac OS X's face counting
--------------------------------------------
        real    2m0.073s
        user    0m33.600s
        sys     0m57.778s


I have a question to FreeType2 developers & users on
Mac OS X: should I apply this patch?

Regards,
mpsuzuki

Index: ChangeLog
===================================================================
RCS file: /cvsroot/freetype/freetype2/ChangeLog,v
retrieving revision 1.1704
diff -u -r1.1704 ChangeLog
--- ChangeLog   3 Mar 2008 08:08:12 -0000       1.1704
+++ ChangeLog   5 Mar 2008 04:19:50 -0000
@@ -1,3 +1,33 @@
+2008-03-04  suzuki toshiya  <address@hidden>
+
+       * src/base/ftmac.c: Improve the count of faces included in FOND
+       resource. Several casts are added for Mac OS X 64bit platforms.
+
+       (append_style_suffixes): New function to append suffixes to base
+       PostScript font name. The suffixes[] is an entry of font name
+       suffix subtable to be synthesized, name[][] is the font name
+       suffix subtable of Style Mapping table in FOND. The synthesized
+       string is stored in Pascal string ps_name.
+
+       (create_psname_from_stylemap): New function to synthesize
+       PostScript name from Style Mapping table in FOND. The name to be
+       synthesized is specified by the face index in the FOND resource.
+
+       (count_faces_fontassoc): New function to count the faces in FOND.
+       Scan all resources referred by Font Association table in FOND,
+       and count the number of available sfnt, POST and bitmap resources
+       (if required). The availability is assured by GetResource(), but
+       it does not guarantee all available resources are unique.
+
+       (count_faces_sfnt, count_faces_scalable): Removed. Replaced by
+       new function count_faces_fontassoc.
+
+       (parse_fond): PostScript name synthesis is moved to new function
+       create_psname_from_stylemap.
+
+       * builds/mac/ftmac.c: Ditto.
+
+
 2008-03-03  Masatoshi Kimura  <address@hidden>
 
        * src/sfnt/ttcmap.c (tt_cmap14_char_map_nondef_binary,
Index: builds/mac/ftmac.c
===================================================================
RCS file: /cvsroot/freetype/freetype2/builds/mac/ftmac.c,v
retrieving revision 1.16
diff -u -r1.16 ftmac.c
--- builds/mac/ftmac.c  21 Feb 2008 23:22:06 -0000      1.16
+++ builds/mac/ftmac.c  5 Mar 2008 04:19:51 -0000
@@ -568,7 +568,8 @@
       return FT_Err_Cannot_Open_Resource;
 
     /* at present, no support for dfont format */
-    err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
+    err = FSOpenResourceFile( &ref, (UniCharCount)0, NULL,
+                              fsRdPerm, res );
     if ( noErr == err )
       return err;
 
@@ -637,12 +638,12 @@
 
   /* Given a PostScript font name, create the Macintosh LWFN file name. */
   static void
-  create_lwfn_name( char*   ps_name,
+  create_lwfn_name( Str255  ps_name,
                     Str255  lwfn_file_name )
   {
     int       max = 5, count = 0;
     FT_Byte*  p = lwfn_file_name;
-    FT_Byte*  q = (FT_Byte*)ps_name;
+    FT_Byte*  q = (FT_Byte*)ps_name + 1;
 
 
     lwfn_file_name[0] = 0;
@@ -666,35 +667,116 @@
   }
 
 
-  static short
-  count_faces_sfnt( char*  fond_data )
+  static void
+  append_style_suffixes( unsigned char*   suffixes,
+                         unsigned char**  names,
+                         unsigned short   string_count,
+                         Str255           ps_name )
+  {
+    int  i, j;
+
+    for ( i = 1; i <= suffixes[0]; i++ )
+    {
+      j = suffixes[i] - 1;
+      if ( j < string_count && names[j] != NULL )
+      {
+        if ( names[j][0] != 0 && ps_name[0] + names[j][0] < 256 )
+        {
+          ft_memcpy( ps_name + ps_name[0] + 1, names[j] + 1,
+                     ( size_t )names[j][0] );
+          ps_name[0] += names[j][0];
+          ps_name[ps_name[0] + 1] = 0;
+        }
+      }
+    }
+  }
+
+
+  static void
+  create_psname_from_stylemap( unsigned char*  stylemap,
+                               Str255          ps_name,
+                               short           face_index )
   {
-    /* The count is 1 greater than the value in the FOND.  */
-    /* Isn't that cute? :-)                                */
+    unsigned char*  p;
+    StyleTable*     style;
+    unsigned short  string_count;
+    unsigned char*  names[64];
+    unsigned char*  suffixes;
+    int             i;
 
-    return EndianS16_BtoN( *( (short*)( fond_data +
-                                        sizeof ( FamRec ) ) ) ) + 1;
+
+    p = stylemap;
+    style = (StyleTable*)p;
+    p += sizeof ( StyleTable );
+    string_count = EndianS16_BtoN( *(short*)(p) );
+    p += sizeof ( short );
+
+    for ( i = 0; i < string_count && i < 64; i++ )
+    {
+      names[i] = p;
+      p       += names[i][0];
+      p++;
+    }
+
+    ps_name[0] = names[0][0];
+    if ( ps_name[0] != 0 )
+    {
+      ft_memcpy(ps_name + 1, names[0] + 1, (size_t)ps_name[0]);
+      ps_name[ps_name[0] + 1] = 0;
+    }
+
+    if ( style->indexes[face_index] < 2 )
+      return;
+
+    if ( style->indexes[face_index] > FT_MIN( string_count, 64 ) )
+      return;
+
+    suffixes = names[style->indexes[face_index] - 1];
+    append_style_suffixes( suffixes, names, string_count, ps_name );
   }
 
 
   static short
-  count_faces_scalable( char*  fond_data )
+  count_faces_fontassoc( Handle   fond,
+                         FT_Bool  only_scalable )
   {
+    char*       fond_data = *fond;
     AsscEntry*  assoc;
-    FamRec*     fond;
     short       i, face, face_all;
 
 
-    fond     = (FamRec*)fond_data;
     face_all = EndianS16_BtoN( *( (short *)( fond_data +
                                              sizeof ( FamRec ) ) ) ) + 1;
     assoc    = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
     face     = 0;
-
     for ( i = 0; i < face_all; i++ )
     {
       if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
-        face++;
+      {
+        /* check fontID exists in known scalable font resource */
+        FamRec*  famrec = (FamRec *)fond_data;
+        char     rtype[][4] = { "sfnt", "POST", };
+        Handle   font_res = NULL;
+        short    j;
+
+
+        for ( j = 0; NULL == font_res && j < sizeof( rtype ) / 4; j++ )
+          font_res = GetResource( EndianU32_BtoN( *(long *)rtype[j] ),
+                                  EndianS16_BtoN( assoc[i].fontID ) );
+
+        if ( NULL != font_res )
+          face ++;
+        else if ( EndianS32_BtoN( famrec->ffStylOff ) )
+        {
+          unsigned char*  p = (unsigned char*)fond_data;
+          Str255          ps_name;
+
+          p += EndianS32_BtoN( famrec->ffStylOff );
+          create_psname_from_stylemap( p, ps_name, i );
+        }
+      }
+      else if ( !only_scalable )
+        face ++;
     }
     return face;
   }
@@ -708,31 +790,32 @@
   */
 
   static void
-  parse_fond( char*   fond_data,
-              short*  have_sfnt,
-              ResID*  sfnt_id,
-              Str255  lwfn_file_name,
-              short   face_index )
+  parse_fond( Handle   fond,
+              short*   have_sfnt,
+              ResID*   sfnt_id,
+              Str255   lwfn_file_name,
+              FT_Long  face_index )
   {
+    char*       fond_data = *fond;
     AsscEntry*  assoc;
     AsscEntry*  base_assoc;
-    FamRec*     fond;
+    FamRec*     famrec;
 
 
     *sfnt_id          = 0;
     *have_sfnt        = 0;
     lwfn_file_name[0] = 0;
 
-    fond       = (FamRec*)fond_data;
-    assoc      = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
+    famrec     = ( FamRec* )fond_data;
+    assoc      = ( AsscEntry* )( fond_data + sizeof ( FamRec ) + 2 );
     base_assoc = assoc;
 
     /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */
-    if ( 47 < face_index )
+    if ( sizeof ( (( StyleTable* )NULL)->indexes ) < face_index )
       return;
 
     /* Let's do a little range checking before we get too excited here */
-    if ( face_index < count_faces_sfnt( fond_data ) )
+    if ( face_index < count_faces_fontassoc( fond, FALSE ) )
     {
       assoc += face_index;        /* add on the face_index! */
 
@@ -750,66 +833,14 @@
       }
     }
 
-    if ( EndianS32_BtoN( fond->ffStylOff ) )
+    if ( EndianS32_BtoN( famrec->ffStylOff ) )
     {
       unsigned char*  p = (unsigned char*)fond_data;
-      StyleTable*     style;
-      unsigned short  string_count;
-      char            ps_name[256];
-      unsigned char*  names[64];
-      int             i;
-
+      Str255          ps_name;
 
-      p += EndianS32_BtoN( fond->ffStylOff );
-      style = (StyleTable*)p;
-      p += sizeof ( StyleTable );
-      string_count = EndianS16_BtoN( *(short*)(p) );
-      p += sizeof ( short );
-
-      for ( i = 0; i < string_count && i < 64; i++ )
-      {
-        names[i] = p;
-        p       += names[i][0];
-        p++;
-      }
-
-      {
-        size_t  ps_name_len = (size_t)names[0][0];
-
-
-        if ( ps_name_len != 0 )
-        {
-          ft_memcpy(ps_name, names[0] + 1, ps_name_len);
-          ps_name[ps_name_len] = 0;
-        }
-        if ( style->indexes[face_index] > 1 &&
-             style->indexes[face_index] <= FT_MIN( string_count, 64 ) )
-        {
-          unsigned char*  suffixes = names[style->indexes[face_index] - 1];
-
-
-          for ( i = 1; i <= suffixes[0]; i++ )
-          {
-            unsigned char*  s;
-            size_t          j = suffixes[i] - 1;
-
-
-            if ( j < string_count && ( s = names[j] ) != NULL )
-            {
-              size_t  s_len = (size_t)s[0];
-
-
-              if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) )
-              {
-                ft_memcpy( ps_name + ps_name_len, s + 1, s_len );
-                ps_name_len += s_len;
-                ps_name[ps_name_len] = 0;
-              }
-            }
-          }
-        }
-      }
 
+      p += EndianS32_BtoN( famrec->ffStylOff );
+      create_psname_from_stylemap( p, ps_name, face_index );
       create_lwfn_name( ps_name, lwfn_file_name );
     }
   }
@@ -819,7 +850,7 @@
   lookup_lwfn_by_fond( const UInt8*      path_fond,
                        ConstStr255Param  base_lwfn,
                        UInt8*            path_lwfn,
-                       int               path_size )
+                       UInt32            path_size )
   {
 
 #if HAVE_FSREF
@@ -918,12 +949,13 @@
     have_sfnt = have_lwfn = 0;
 
     HLock( fond );
-    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
+    parse_fond( fond, &have_sfnt, &sfnt_id, lwfn_file_name,
+                ( FT_Long ) 0 );
 
     if ( lwfn_file_name[0] )
     {
       err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
-                                 buff, sizeof ( buff )  );
+                                 buff, ( UInt32 ) sizeof ( buff ) );
       if ( FT_Err_Ok == err )
         have_lwfn = 1;
     }
@@ -931,7 +963,7 @@
     if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
       num_faces = 1;
     else
-      num_faces = count_faces_scalable( *fond );
+      num_faces = count_faces_fontassoc( fond, TRUE );
 
     HUnlock( fond );
     return num_faces;
@@ -968,7 +1000,7 @@
 
     for (;;)
     {
-      post_data = Get1Resource( FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
+      post_data = Get1Resource( ( ResType )FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
                                 res_id++ );
       if ( post_data == NULL )
         break;  /* we are done */
@@ -1008,7 +1040,7 @@
 
     for (;;)
     {
-      post_data = Get1Resource( FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
+      post_data = Get1Resource( ( ResType )FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
                                 res_id++ );
       if ( post_data == NULL )
         break;  /* we are done */
@@ -1211,12 +1243,13 @@
     int        is_cff;
 
 
-    sfnt = GetResource( FT_MAKE_TAG( 's', 'f', 'n', 't' ), sfnt_id );
+    sfnt = GetResource( ( ResType )FT_MAKE_TAG( 's', 'f', 'n', 't' ),
+                        sfnt_id );
     if ( sfnt == NULL )
       return FT_Err_Invalid_Handle;
 
-    sfnt_size = (FT_ULong)GetHandleSize( sfnt );
-    if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
+    sfnt_size = ( FT_ULong ) GetHandleSize( sfnt );
+    if ( FT_ALLOC( sfnt_data, ( FT_Long ) sfnt_size ) )
     {
       ReleaseResource( sfnt );
       return error;
@@ -1265,7 +1298,7 @@
     num_faces_in_res = 0;
     for ( res_index = 1; ; ++res_index )
     {
-      fond = Get1IndResource( FT_MAKE_TAG( 'F', 'O', 'N', 'D' ),
+      fond = Get1IndResource( ( ResType )FT_MAKE_TAG( 'F', 'O', 'N', 'D' ),
                               res_index );
       if ( ResError() )
         break;
@@ -1306,11 +1339,11 @@
 
     GetResInfo( fond, &fond_id, &fond_type, fond_name );
     if ( ResError() != noErr ||
-         fond_type != FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) )
+         fond_type != ( ResType )FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) )
       return FT_Err_Invalid_File_Format;
 
     HLock( fond );
-    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
+    parse_fond( fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
     HUnlock( fond );
 
     if ( lwfn_file_name[0] )
@@ -1334,12 +1367,14 @@
         if ( noErr != err )
           goto found_no_lwfn_file;
 
-        err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) );
+        err = FSRefMakePath( &ref, path_fond,
+                             ( UInt32 ) sizeof( path_fond ) );
         if ( noErr != err )
           goto found_no_lwfn_file;
 
         error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
-                                     path_lwfn, sizeof ( path_lwfn ) );
+                                     path_lwfn,
+                                     ( UInt32 ) sizeof( path_lwfn ) );
         if ( FT_Err_Ok == error )
           have_lwfn = 1;
       }
@@ -1416,7 +1451,7 @@
 
     /* LWFN is a (very) specific file format, check for it explicitly */
     file_type = get_file_type_from_path( pathname );
-    if ( file_type == FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) )
+    if ( file_type == ( OSType )FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) )
       return FT_New_Face_From_LWFN( library, pathname, face_index, aface );
 
     /* Otherwise the file type doesn't matter (there are more than  */
@@ -1513,7 +1548,7 @@
     if ( !ref )
       return FT_Err_Invalid_Argument;
 
-    err = FSRefMakePath( ref, pathname, sizeof ( pathname ) );
+    err = FSRefMakePath( ref, pathname, ( UInt32 ) sizeof ( pathname ) );
     if ( err )
       error = FT_Err_Cannot_Open_Resource;
 
Index: src/base/ftmac.c
===================================================================
RCS file: /cvsroot/freetype/freetype2/src/base/ftmac.c,v
retrieving revision 1.65
diff -u -r1.65 ftmac.c
--- src/base/ftmac.c    21 Feb 2008 23:22:06 -0000      1.65
+++ src/base/ftmac.c    5 Mar 2008 04:19:51 -0000
@@ -271,7 +271,8 @@
       return FT_Err_Cannot_Open_Resource;
 
     /* at present, no support for dfont format */
-    err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
+    err = FSOpenResourceFile( &ref, (UniCharCount)0, NULL,
+                              fsRdPerm, res );
     if ( noErr == err )
       return err;
 
@@ -304,12 +305,12 @@
 
   /* Given a PostScript font name, create the Macintosh LWFN file name. */
   static void
-  create_lwfn_name( char*   ps_name,
+  create_lwfn_name( Str255  ps_name,
                     Str255  lwfn_file_name )
   {
     int       max = 5, count = 0;
     FT_Byte*  p = lwfn_file_name;
-    FT_Byte*  q = (FT_Byte*)ps_name;
+    FT_Byte*  q = (FT_Byte*)ps_name + 1;
 
 
     lwfn_file_name[0] = 0;
@@ -333,35 +334,106 @@
   }
 
 
-  static short
-  count_faces_sfnt( char*  fond_data )
+  static void
+  append_style_suffixes( UInt8*   suffixes,
+                         UInt8**  names,
+                         UInt16   string_count,
+                         Str255   ps_name )
   {
-    /* The count is 1 greater than the value in the FOND.  */
-    /* Isn't that cute? :-)                                */
+    UInt8  i, j;
+
+    for ( i = 1; i <= suffixes[0]; i++ )
+    {
+      j = suffixes[i] - 1;
+      if ( j < string_count && names[j] != NULL )
+      {
+        if ( names[j][0] != 0 && ps_name[0] + names[j][0] < 256 )
+        {
+          ft_memcpy( ps_name + ps_name[0] + 1, names[j] + 1,
+                     ( size_t )names[j][0] );
+          ps_name[0] += names[j][0];
+          ps_name[ps_name[0] + 1] = 0;
+        }
+      }
+    }
+  }
+
+
+  static void
+  create_psname_from_stylemap( UInt8*   stylemap,
+                               Str255   ps_name,
+                               FT_Long  face_index )
+  {
+    UInt8*  p;
+    UInt16  i, string_count;
+    UInt8*  names[64]; /* XXX: Apple had never defined such limit */
+    UInt8*  suffixes;
+    StyleTable*  style;
+
+
+    p = stylemap;
+    style = ( StyleTable* )p;
+    p += sizeof ( StyleTable );
+    string_count = EndianS16_BtoN( *(SInt16 *)(p) );
+    p += sizeof ( SInt16 );
+
+    for ( i = 0; i < string_count && i < 64; i++ )
+    {
+      names[i] = p;
+      p       += names[i][0];
+      p++;
+    }
+
+    ps_name[0] = names[0][0];
+    if ( ps_name[0] != 0 )
+    {
+      ft_memcpy(ps_name + 1, names[0] + 1, (size_t)ps_name[0]);
+      ps_name[ps_name[0] + 1] = 0;
+    }
+
+    if ( style->indexes[face_index] < 2 )
+      return;
+
+    if ( style->indexes[face_index] > FT_MIN( string_count, 64 ) )
+      return;
 
-    return EndianS16_BtoN( *( (short*)( fond_data +
-                                        sizeof ( FamRec ) ) ) ) + 1;
+    suffixes = names[style->indexes[face_index] - 1];
+    append_style_suffixes( suffixes, names, string_count, ps_name );
   }
 
 
   static short
-  count_faces_scalable( char*  fond_data )
+  count_faces_fontassoc( Handle   fond,
+                         FT_Bool  only_scalable )
   {
+    char*       fond_data = *fond;
+    UInt16      i, face, face_all;
     AsscEntry*  assoc;
-    FamRec*     fond;
-    short       i, face, face_all;
 
 
-    fond     = (FamRec*)fond_data;
-    face_all = EndianS16_BtoN( *( (short *)( fond_data +
+    face_all = EndianS16_BtoN( *( (SInt16 *)( fond_data +
                                              sizeof ( FamRec ) ) ) ) + 1;
     assoc    = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
     face     = 0;
-
     for ( i = 0; i < face_all; i++ )
     {
       if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
-        face++;
+      {
+        /* check fontID exists in known scalable font resource */
+        UInt8    rtype[][4] = { "sfnt", "POST", };
+        Handle   font_res = NULL;
+        UInt16   j;
+
+
+        for ( j = 0; NULL == font_res && j < sizeof( rtype ) / 4; j++ )
+          font_res = GetResource( EndianU32_BtoN( *(UInt32 *)rtype[j] ),
+                                  EndianS16_BtoN( assoc[i].fontID ) );
+
+        if ( NULL != font_res )
+          face ++;
+      }
+      else if ( !only_scalable )
+        face ++;
     }
     return face;
   }
@@ -376,31 +448,32 @@
 
 
   static void
-  parse_fond( char*   fond_data,
-              short*  have_sfnt,
-              ResID*  sfnt_id,
-              Str255  lwfn_file_name,
-              short   face_index )
+  parse_fond( Handle   fond,
+              short*   have_sfnt,
+              ResID*   sfnt_id,
+              Str255   lwfn_file_name,
+              FT_Long  face_index )
   {
+    char*       fond_data = *fond;
     AsscEntry*  assoc;
     AsscEntry*  base_assoc;
-    FamRec*     fond;
+    FamRec*     famrec;
 
 
     *sfnt_id          = 0;
     *have_sfnt        = 0;
     lwfn_file_name[0] = 0;
 
-    fond       = (FamRec*)fond_data;
-    assoc      = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
+    famrec     = ( FamRec* )fond_data;
+    assoc      = ( AsscEntry* )( fond_data + sizeof ( FamRec ) + 2 );
     base_assoc = assoc;
 
-    /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */
-    if ( 47 < face_index )
+    /* the max face in a FOND is the size of StyleTable.indexes[] = 48 */
+    if ( sizeof ( (( StyleTable* )NULL)->indexes ) < face_index )
       return;
 
     /* Let's do a little range checking before we get too excited here */
-    if ( face_index < count_faces_sfnt( fond_data ) )
+    if ( face_index < count_faces_fontassoc( fond, FALSE ) )
     {
       assoc += face_index;        /* add on the face_index! */
 
@@ -418,66 +491,14 @@
       }
     }
 
-    if ( EndianS32_BtoN( fond->ffStylOff ) )
+    if ( EndianS32_BtoN( famrec->ffStylOff ) )
     {
-      unsigned char*  p = (unsigned char*)fond_data;
-      StyleTable*     style;
-      unsigned short  string_count;
-      char            ps_name[256];
-      unsigned char*  names[64];
-      int             i;
-
-
-      p += EndianS32_BtoN( fond->ffStylOff );
-      style = (StyleTable*)p;
-      p += sizeof ( StyleTable );
-      string_count = EndianS16_BtoN( *(short*)(p) );
-      p += sizeof ( short );
-
-      for ( i = 0; i < string_count && i < 64; i++ )
-      {
-        names[i] = p;
-        p       += names[i][0];
-        p++;
-      }
-
-      {
-        size_t  ps_name_len = (size_t)names[0][0];
+      UInt8*  p = (UInt8*)fond_data;
+      Str255  ps_name;
 
 
-        if ( ps_name_len != 0 )
-        {
-          ft_memcpy(ps_name, names[0] + 1, ps_name_len);
-          ps_name[ps_name_len] = 0;
-        }
-        if ( style->indexes[face_index] > 1 &&
-             style->indexes[face_index] <= FT_MIN( string_count, 64 ) )
-        {
-          unsigned char*  suffixes = names[style->indexes[face_index] - 1];
-
-
-          for ( i = 1; i <= suffixes[0]; i++ )
-          {
-            unsigned char*  s;
-            size_t          j = suffixes[i] - 1;
-
-
-            if ( j < string_count && ( s = names[j] ) != NULL )
-            {
-              size_t  s_len = (size_t)s[0];
-
-
-              if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) )
-              {
-                ft_memcpy( ps_name + ps_name_len, s + 1, s_len );
-                ps_name_len += s_len;
-                ps_name[ps_name_len] = 0;
-              }
-            }
-          }
-        }
-      }
-
+      p += EndianS32_BtoN( famrec->ffStylOff );
+      create_psname_from_stylemap( p, ps_name, face_index );
       create_lwfn_name( ps_name, lwfn_file_name );
     }
   }
@@ -487,7 +508,7 @@
   lookup_lwfn_by_fond( const UInt8*      path_fond,
                        ConstStr255Param  base_lwfn,
                        UInt8*            path_lwfn,
-                       size_t            path_size )
+                       UInt32            path_size )
   {
     FSRef   ref, par_ref;
     size_t  dirname_len;
@@ -540,12 +561,13 @@
 
     have_sfnt = have_lwfn = 0;
 
-    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
+    parse_fond( fond, &have_sfnt, &sfnt_id, lwfn_file_name,
+                ( FT_Long ) 0 );
 
     if ( lwfn_file_name[0] )
     {
       err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
-                                 buff, sizeof ( buff )  );
+                                 buff, ( UInt32 ) sizeof ( buff )  );
       if ( FT_Err_Ok == err )
         have_lwfn = 1;
     }
@@ -553,7 +575,7 @@
     if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
       num_faces = 1;
     else
-      num_faces = count_faces_scalable( *fond );
+      num_faces = count_faces_fontassoc( fond, TRUE );
 
     return num_faces;
   }
@@ -589,7 +611,7 @@
 
     for (;;)
     {
-      post_data = Get1Resource( FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
+      post_data = Get1Resource( ( ResType )FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
                                 res_id++ );
       if ( post_data == NULL )
         break;  /* we are done */
@@ -629,7 +651,7 @@
 
     for (;;)
     {
-      post_data = Get1Resource( FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
+      post_data = Get1Resource( ( ResType )FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
                                 res_id++ );
       if ( post_data == NULL )
         break;  /* we are done */
@@ -832,12 +854,13 @@
     int        is_cff;
 
 
-    sfnt = GetResource( FT_MAKE_TAG( 's', 'f', 'n', 't' ), sfnt_id );
+    sfnt = GetResource( ( ResType )FT_MAKE_TAG( 's', 'f', 'n', 't' ),
+                        sfnt_id );
     if ( sfnt == NULL )
       return FT_Err_Invalid_Handle;
 
-    sfnt_size = (FT_ULong)GetHandleSize( sfnt );
-    if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
+    sfnt_size = ( FT_ULong ) GetHandleSize( sfnt );
+    if ( FT_ALLOC( sfnt_data, ( FT_Long ) sfnt_size ) )
     {
       ReleaseResource( sfnt );
       return error;
@@ -884,7 +907,7 @@
     num_faces_in_res = 0;
     for ( res_index = 1; ; ++res_index )
     {
-      fond = Get1IndResource( FT_MAKE_TAG( 'F', 'O', 'N', 'D' ),
+      fond = Get1IndResource( ( ResType )FT_MAKE_TAG( 'F', 'O', 'N', 'D' ),
                               res_index );
       if ( ResError() )
         break;
@@ -924,10 +947,11 @@
 
 
     GetResInfo( fond, &fond_id, &fond_type, fond_name );
-    if ( ResError() != noErr || fond_type != FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) 
)
+    if ( ResError() != noErr ||
+         fond_type != ( ResType )FT_MAKE_TAG( 'F', 'O', 'N', 'D' ) )
       return FT_Err_Invalid_File_Format;
 
-    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
+    parse_fond( fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
 
     if ( lwfn_file_name[0] )
     {
@@ -948,12 +972,14 @@
         if ( noErr != err )
           goto found_no_lwfn_file;
 
-        err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) );
+        err = FSRefMakePath( &ref, path_fond,
+                             ( UInt32 ) sizeof( path_fond ) );
         if ( noErr != err )
           goto found_no_lwfn_file;
 
         error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
-                                     path_lwfn, sizeof ( path_lwfn ) );
+                                     path_lwfn,
+                                     ( UInt32 ) sizeof( path_lwfn ) );
         if ( FT_Err_Ok == error )
           have_lwfn = 1;
       }
@@ -991,7 +1017,7 @@
 
     /* LWFN is a (very) specific file format, check for it explicitly */
     file_type = get_file_type_from_path( pathname );
-    if ( file_type == FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) )
+    if ( file_type == ( OSType )FT_MAKE_TAG( 'L', 'W', 'F', 'N' ) )
       return FT_New_Face_From_LWFN( library, pathname, face_index, aface );
 
     /* Otherwise the file type doesn't matter (there are more than  */
@@ -1076,7 +1102,7 @@
     if ( !ref )
       return FT_Err_Invalid_Argument;
 
-    err = FSRefMakePath( ref, pathname, sizeof ( pathname ) );
+    err = FSRefMakePath( ref, pathname, ( UInt32 ) sizeof ( pathname ) );
     if ( err )
       error = FT_Err_Cannot_Open_Resource;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]