Sync with trunk r47367
[reactos.git] / lib / 3rdparty / freetype / src / base / ftmac.c
index fd6201a..63f927d 100644 (file)
@@ -8,7 +8,8 @@
 /*  This file is for Mac OS X only; see builds/mac/ftoldmac.c for          */
 /*  classic platforms built by MPW.                                        */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,         */
+/*            2009 by                                                      */
 /*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -67,7 +68,9 @@
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
+#include FT_TRUETYPE_TAGS_H
 #include FT_INTERNAL_STREAM_H
+#include "ftbase.h"
 
   /* This is for Mac OS X.  Without redefinition, OS_INLINE */
   /* expands to `static inline' which doesn't survive the   */
 #undef  OS_INLINE
 #define OS_INLINE  static __inline__
 #endif
-#include <Carbon/Carbon.h>
 
-#ifndef HFS_MAXPATHLEN
-#define HFS_MAXPATHLEN  1024
+  /* `configure' checks the availability of `ResourceIndex' strictly */
+  /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always.  If it is      */
+  /* not set (e.g., a build without `configure'), the availability   */
+  /* is guessed from the SDK version.                                */
+#ifndef HAVE_TYPE_RESOURCE_INDEX
+#if !defined( MAC_OS_X_VERSION_10_5 ) || \
+    ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 )
+#define HAVE_TYPE_RESOURCE_INDEX 0
+#else
+#define HAVE_TYPE_RESOURCE_INDEX 1
+#endif
+#endif /* !HAVE_TYPE_RESOURCE_INDEX */
+
+#if ( HAVE_TYPE_RESOURCE_INDEX == 0 )
+  typedef short  ResourceIndex;
 #endif
 
+#include <CoreServices/CoreServices.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <sys/syslimits.h> /* PATH_MAX */
+
+  /* Don't want warnings about our own use of deprecated functions. */
 #define FT_DEPRECATED_ATTRIBUTE
 
 #include FT_MAC_H
 
-  /* undefine blocking-macros in ftmac.h */
-#undef FT_GetFile_From_Mac_Name( a, b, c )
-#undef FT_GetFile_From_Mac_ATS_Name( a, b, c )
-#undef FT_New_Face_From_FSSpec( a, b, c, d )
+#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */
+#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault
+#endif
 
 
   /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over
 #endif
 
 
+  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */
   FT_EXPORT_DEF( FT_Error )
   FT_GetFile_From_Mac_Name( const char*  fontName,
                             FSSpec*      pathSpec,
 
   /* Private function.                                         */
   /* The FSSpec type has been discouraged for a long time,     */
-  /* but for some reason, there is no FSRef version of         */
-  /* ATSFontGetFileSpecification(), so we made our own.        */
-  /* Apple will provide one eventually.                        */
+  /* unfortunately an FSRef replacement API for                */
+  /* ATSFontGetFileSpecification() is only available in        */
+  /* Mac OS X 10.5 and later.                                  */
   static OSStatus
   FT_ATSFontGetFileReference( ATSFontRef  ats_font_id,
                               FSRef*      ats_font_ref )
   {
-#if __LP64__
+#if defined( MAC_OS_X_VERSION_10_5 ) && \
+    ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
+    OSStatus  err;
+
+    err = ATSFontGetFileReference( ats_font_id, ats_font_ref );
+
+    return err;
+#elif __LP64__ /* No 64bit Carbon API on legacy platforms */
     FT_UNUSED( ats_font_id );
     FT_UNUSED( ats_font_ref );
 
+
     return fnfErr;
-#else
+#else /* 32bit Carbon API on legacy platforms */
     OSStatus  err;
     FSSpec    spec;
 
                                 FSSpec*      pathSpec,
                                 FT_Long*     face_index )
   {
-#if __LP64__
+#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
+      ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
     FT_UNUSED( fontName );
     FT_UNUSED( pathSpec );
     FT_UNUSED( face_index );
 
 
   static OSErr
-  FT_FSPathMakeRes( const UInt8*  pathname,
-                    short*        res )
+  FT_FSPathMakeRes( const UInt8*    pathname,
+                    ResFileRefNum*  res )
   {
     OSErr  err;
     FSRef  ref;
   static void
   parse_fond( char*   fond_data,
               short*  have_sfnt,
-              short*  sfnt_id,
+              ResID*  sfnt_id,
               Str255  lwfn_file_name,
               short   face_index )
   {
     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 )
+      return;
+
     /* Let's do a little range checking before we get too excited here */
     if ( face_index < count_faces_sfnt( fond_data ) )
     {
           ft_memcpy(ps_name, names[0] + 1, ps_name_len);
           ps_name[ps_name_len] = 0;
         }
-        if ( style->indexes[0] > 1 )
+        if ( style->indexes[face_index] > 1 &&
+             style->indexes[face_index] <= FT_MIN( string_count, 64 ) )
         {
-          unsigned char*  suffixes = names[style->indexes[0] - 1];
+          unsigned char*  suffixes = names[style->indexes[face_index] - 1];
 
 
           for ( i = 1; i <= suffixes[0]; i++ )
                        UInt8*            path_lwfn,
                        size_t            path_size )
   {
-    FSRef  ref, par_ref;
-    int    dirname_len;
+    FSRef   ref, par_ref;
+    size_t  dirname_len;
 
 
     /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */
   count_faces( Handle        fond,
                const UInt8*  pathname )
   {
-    short     sfnt_id;
+    ResID     sfnt_id;
     short     have_sfnt, have_lwfn;
     Str255    lwfn_file_name;
-    UInt8     buff[HFS_MAXPATHLEN];
+    UInt8     buff[PATH_MAX];
     FT_Error  err;
     short     num_faces;
 
      chunks are often not organized that way, so we glue chunks
      of the same type together. */
   static FT_Error
-  read_lwfn( FT_Memory  memory,
-             short      res,
-             FT_Byte**  pfb_data,
-             FT_ULong*  size )
+  read_lwfn( FT_Memory      memory,
+             ResFileRefNum  res,
+             FT_Byte**      pfb_data,
+             FT_ULong*      size )
   {
     FT_Error       error = FT_Err_Ok;
-    short          res_id;
+    ResID          res_id;
     unsigned char  *buffer, *p, *size_p = NULL;
     FT_ULong       total_size = 0;
     FT_ULong       old_total_size = 0;
 
     for (;;)
     {
-      post_data = Get1Resource( 'POST', res_id++ );
+      post_data = Get1Resource( TTAG_POST, res_id++ );
       if ( post_data == NULL )
         break;  /* we are done */
 
 
     for (;;)
     {
-      post_data = Get1Resource( 'POST', res_id++ );
+      post_data = Get1Resource( TTAG_POST, res_id++ );
       if ( post_data == NULL )
         break;  /* we are done */
 
   }
 
 
-  /* Finalizer for a memory stream; gets called by FT_Done_Face().
-     It frees the memory it uses. */
-  static void
-  memory_stream_close( FT_Stream  stream )
-  {
-    FT_Memory  memory = stream->memory;
-
-
-    FT_FREE( stream->base );
-
-    stream->size  = 0;
-    stream->base  = 0;
-    stream->close = 0;
-  }
-
-
-  /* Create a new memory stream from a buffer and a size. */
-  static FT_Error
-  new_memory_stream( FT_Library           library,
-                     FT_Byte*             base,
-                     FT_ULong             size,
-                     FT_Stream_CloseFunc  close,
-                     FT_Stream*           astream )
-  {
-    FT_Error   error;
-    FT_Memory  memory;
-    FT_Stream  stream;
-
-
-    if ( !library )
-      return FT_Err_Invalid_Library_Handle;
-
-    if ( !base )
-      return FT_Err_Invalid_Argument;
-
-    *astream = 0;
-    memory = library->memory;
-    if ( FT_NEW( stream ) )
-      goto Exit;
-
-    FT_Stream_OpenMemory( stream, base, size );
-
-    stream->close = close;
-
-    *astream = stream;
-
-  Exit:
-    return error;
-  }
-
-
-  /* Create a new FT_Face given a buffer and a driver name. */
-  static FT_Error
-  open_face_from_buffer( FT_Library  library,
-                         FT_Byte*    base,
-                         FT_ULong    size,
-                         FT_Long     face_index,
-                         char*       driver_name,
-                         FT_Face*    aface )
-  {
-    FT_Open_Args  args;
-    FT_Error      error;
-    FT_Stream     stream;
-    FT_Memory     memory = library->memory;
-
-
-    error = new_memory_stream( library,
-                               base,
-                               size,
-                               memory_stream_close,
-                               &stream );
-    if ( error )
-    {
-      FT_FREE( base );
-      return error;
-    }
-
-    args.flags  = FT_OPEN_STREAM;
-    args.stream = stream;
-    if ( driver_name )
-    {
-      args.flags  = args.flags | FT_OPEN_DRIVER;
-      args.driver = FT_Get_Module( library, driver_name );
-    }
-
-    /* At this point, face_index has served its purpose;      */
-    /* whoever calls this function has already used it to     */
-    /* locate the correct font data.  We should not propagate */
-    /* this index to FT_Open_Face() (unless it is negative).  */
-
-    if ( face_index > 0 )
-      face_index = 0;
-
-    error = FT_Open_Face( library, &args, face_index, aface );
-    if ( error == FT_Err_Ok )
-      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
-    else
-      FT_Stream_Free( stream, 0 );
-
-    return error;
-  }
-
-
-  /* Create a new FT_Face from a file spec to an LWFN file. */
+  /* Create a new FT_Face from a file path to an LWFN file. */
   static FT_Error
   FT_New_Face_From_LWFN( FT_Library    library,
                          const UInt8*  pathname,
                          FT_Long       face_index,
                          FT_Face*      aface )
   {
-    FT_Byte*  pfb_data;
-    FT_ULong  pfb_size;
-    FT_Error  error;
-    short     res;
+    FT_Byte*       pfb_data;
+    FT_ULong       pfb_size;
+    FT_Error       error;
+    ResFileRefNum  res;
 
 
     if ( noErr != FT_FSPathMakeRes( pathname, &res ) )
   /* Create a new FT_Face from an SFNT resource, specified by res ID. */
   static FT_Error
   FT_New_Face_From_SFNT( FT_Library  library,
-                         short       sfnt_id,
+                         ResID       sfnt_id,
                          FT_Long     face_index,
                          FT_Face*    aface )
   {
     size_t     sfnt_size;
     FT_Error   error  = FT_Err_Ok;
     FT_Memory  memory = library->memory;
-    int        is_cff;
+    int        is_cff, is_sfnt_ps;
 
 
-    sfnt = GetResource( 'sfnt', sfnt_id );
-    if ( ResError() )
+    sfnt = GetResource( TTAG_sfnt, sfnt_id );
+    if ( sfnt == NULL )
       return FT_Err_Invalid_Handle;
 
     sfnt_size = (FT_ULong)GetHandleSize( sfnt );
     ft_memcpy( sfnt_data, *sfnt, sfnt_size );
     ReleaseResource( sfnt );
 
-    is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' &&
-                              sfnt_data[1] == 'T' &&
-                              sfnt_data[2] == 'T' &&
-                              sfnt_data[3] == 'O';
+    is_cff     = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
+    is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 );
 
-    return open_face_from_buffer( library,
-                                  sfnt_data,
-                                  sfnt_size,
-                                  face_index,
-                                  is_cff ? "cff" : "truetype",
-                                  aface );
+    if ( is_sfnt_ps )
+    {
+      FT_Stream  stream;
+
+
+      if ( FT_NEW( stream ) )
+        goto Try_OpenType;
+
+      FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );
+      if ( !open_face_PS_from_sfnt_stream( library,
+                                           stream,
+                                           face_index,
+                                           0, NULL,
+                                           aface ) )
+      {
+        FT_Stream_Close( stream );
+        FT_FREE( stream );
+        FT_FREE( sfnt_data );
+        goto Exit;
+      }
+
+      FT_FREE( stream );
+    }
+  Try_OpenType:
+    error = open_face_from_buffer( library,
+                                   sfnt_data,
+                                   sfnt_size,
+                                   face_index,
+                                   is_cff ? "cff" : "truetype",
+                                   aface );
+  Exit:
+    return error;
   }
 
 
-  /* Create a new FT_Face from a file spec to a suitcase file. */
+  /* Create a new FT_Face from a file path to a suitcase file. */
   static FT_Error
   FT_New_Face_From_Suitcase( FT_Library    library,
                              const UInt8*  pathname,
                              FT_Long       face_index,
                              FT_Face*      aface )
   {
-    FT_Error  error = FT_Err_Cannot_Open_Resource;
-    short     res_ref, res_index;
-    Handle    fond;
-    short     num_faces_in_res, num_faces_in_fond;
+    FT_Error       error = FT_Err_Cannot_Open_Resource;
+    ResFileRefNum  res_ref;
+    ResourceIndex  res_index;
+    Handle         fond;
+    short          num_faces_in_res, num_faces_in_fond;
 
 
     if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) )
     num_faces_in_res = 0;
     for ( res_index = 1; ; ++res_index )
     {
-      fond = Get1IndResource( 'FOND', res_index );
+      fond = Get1IndResource( TTAG_FOND, res_index );
       if ( ResError() )
         break;
 
     }
 
     CloseResFile( res_ref );
-    if ( FT_Err_Ok == error && NULL != aface )
+    if ( FT_Err_Ok == error && NULL != aface && NULL != *aface )
       (*aface)->num_faces = num_faces_in_res;
     return error;
   }
                          FT_Long     face_index,
                          FT_Face*    aface )
   {
-    short     sfnt_id, have_sfnt, have_lwfn = 0;
-    short     fond_id;
+    short     have_sfnt, have_lwfn = 0;
+    ResID     sfnt_id, fond_id;
     OSType    fond_type;
     Str255    fond_name;
     Str255    lwfn_file_name;
-    UInt8     path_lwfn[HFS_MAXPATHLEN];
+    UInt8     path_lwfn[PATH_MAX];
     OSErr     err;
     FT_Error  error = FT_Err_Ok;
 
 
     GetResInfo( fond, &fond_id, &fond_type, fond_name );
-    if ( ResError() != noErr || fond_type != 'FOND' )
+    if ( ResError() != noErr || fond_type != TTAG_FOND )
       return FT_Err_Invalid_File_Format;
 
     parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
 
     if ( lwfn_file_name[0] )
     {
-      short  res;
+      ResFileRefNum  res;
 
 
       res = HomeResFile( fond );
         goto found_no_lwfn_file;
 
       {
-        UInt8  path_fond[HFS_MAXPATHLEN];
+        UInt8  path_fond[PATH_MAX];
         FSRef  ref;
 
 
 
     /* LWFN is a (very) specific file format, check for it explicitly */
     file_type = get_file_type_from_path( pathname );
-    if ( file_type == 'LWFN' )
+    if ( file_type == TTAG_LWFN )
       return FT_New_Face_From_LWFN( library, pathname, face_index, aface );
 
     /* Otherwise the file type doesn't matter (there are more than  */
   /*    FT_New_Face_From_FSRef is identical to FT_New_Face except it       */
   /*    accepts an FSRef instead of a path.                                */
   /*                                                                       */
+  /* This function is deprecated because Carbon data types (FSRef)         */
+  /* are not cross-platform, and thus not suitable for the freetype API.   */
   FT_EXPORT_DEF( FT_Error )
   FT_New_Face_From_FSRef( FT_Library    library,
                           const FSRef*  ref,
     FT_Error      error;
     FT_Open_Args  args;
     OSErr   err;
-    UInt8   pathname[HFS_MAXPATHLEN];
+    UInt8   pathname[PATH_MAX];
 
 
     if ( !ref )
   /*    FT_New_Face_From_FSSpec is identical to FT_New_Face except it      */
   /*    accepts an FSSpec instead of a path.                               */
   /*                                                                       */
+  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */
   FT_EXPORT_DEF( FT_Error )
   FT_New_Face_From_FSSpec( FT_Library     library,
                            const FSSpec*  spec,
                            FT_Long        face_index,
                            FT_Face*       aface )
   {
-#if __LP64__
+#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
+      ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
     FT_UNUSED( library );
     FT_UNUSED( spec );
     FT_UNUSED( face_index );