shithub: freetype+ttf2subf

Download patch

ref: 754353343ecd27582ed86cd9fd07d31ab1df883c
parent: 460355a5ea271c8e5eb247082744b46a0e5c244e
author: Werner Lemberg <[email protected]>
date: Wed Feb 25 07:58:54 EST 2004

Provide generic access to MacOS resource forks.

* src/base/ftrfork.c, include/freetype/internal/ftrfork.h: New
files.

* src/base/ftobjs.c: Include FT_INTERNAL_RFORK_H.
(Mac_Read_POST_Resource, Mac_Read_sfnt_Resource): Remove arguments
`resource_listoffset' and `resource_data' and adapt code
accordingly.  These values are calculated outside of the function
now.
Add new argument `offsets'.
(IsMacResource): Use `FT_Raccess_Get_HeaderInfo' and
`FT_Raccess_Get_DataOffsets'.
(load_face_in_embedded_rfork): New function.
(load_mac_face): Use load_face_in_embedded_rfork.
(ft_input_stream_new): Renamed to...
(FT_Stream_New): This.  Use FT_BASE_DEF.  Updated all callers.
(ft_input_stream_free): Renamed to...
(FT_Stream_Free): This.  Use FT_BASE_DEF.  Updated all callers.

* src/base/ftbase.c: Include ftrfork.c.

* src/base/rules.mk (BASE_SRC), src/base/Jamfile: Updated.

* include/freetype/internal/internal.h (FT_INTERNAL_RFORK_H):
New macro.

* include/freetype/internal/fttrace.h: Added `rfork' as a new
trace definition.

* include/freetype/internal/ftstream.h: Declare FT_Stream_New and
FT_Stream_Free.

* include/freetype/config/ftoption.h, devel/ftoption.h
(FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK): New option.

* include/freetype/config/ftstdlib.h (ft_strrchr): New macro.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2004-02-17  Masatake YAMATO  <[email protected]>
+
+	Provide generic access to MacOS resource forks.
+
+	* src/base/ftrfork.c, include/freetype/internal/ftrfork.h: New
+	files.
+
+	* src/base/ftobjs.c: Include FT_INTERNAL_RFORK_H.
+	(Mac_Read_POST_Resource, Mac_Read_sfnt_Resource): Remove arguments
+	`resource_listoffset' and `resource_data' and adapt code
+	accordingly.  These values are calculated outside of the function
+	now.
+	Add new argument `offsets'.
+	(IsMacResource): Use `FT_Raccess_Get_HeaderInfo' and 
+	`FT_Raccess_Get_DataOffsets'.
+	(load_face_in_embedded_rfork): New function.
+	(load_mac_face): Use load_face_in_embedded_rfork.
+	(ft_input_stream_new): Renamed to...
+	(FT_Stream_New): This.  Use FT_BASE_DEF.  Updated all callers.
+	(ft_input_stream_free): Renamed to...
+	(FT_Stream_Free): This.  Use FT_BASE_DEF.  Updated all callers.
+
+	* src/base/ftbase.c: Include ftrfork.c.
+
+	* src/base/rules.mk (BASE_SRC), src/base/Jamfile: Updated.
+
+	* include/freetype/internal/internal.h (FT_INTERNAL_RFORK_H):
+	New macro.
+
+	* include/freetype/internal/fttrace.h: Added `rfork' as a new
+	trace definition.
+
+	* include/freetype/internal/ftstream.h: Declare FT_Stream_New and
+	FT_Stream_Free.
+
+	* include/freetype/config/ftoption.h, devel/ftoption.h
+	(FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK): New option.
+
+	* include/freetype/config/ftstdlib.h (ft_strrchr): New macro.
+
 2004-02-23  Werner Lemberg  <[email protected]>
 
 	* docs/CHANGES: Updated.
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    User-selectable configuration macros (specification only).           */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003 by                                     */
+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -228,6 +228,29 @@
   /*   Note that the `FOND' resource isn't checked.                        */
   /*                                                                       */
 #define FT_CONFIG_OPTION_MAC_FONTS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Guessing methods to access embedded resource forks                    */
+  /*                                                                       */
+  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */
+  /*   GNU/Linux).                                                         */
+  /*                                                                       */
+  /*   Resource forks which include fonts data are stored sometimes in     */
+  /*   locations which users or developers don't expected.  In some cases, */
+  /*   resource forks start with some offset from the head of a file.  In  */
+  /*   other cases, the actual resource fork is stored in file different   */
+  /*   from what the user specifies.  If this option is activated,         */
+  /*   FreeType tries to guess whether such offsets or different file      */
+  /*   names must be used.                                                 */
+  /*                                                                       */
+  /*   Note that normal, direct access of resource forks is controlled via */
+  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */
+  /*                                                                       */
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
+#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
+#endif
 
 
   /*************************************************************************/
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    User-selectable configuration macros (specification only).           */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003 by                                     */
+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -228,6 +228,29 @@
   /*   Note that the `FOND' resource isn't checked.                        */
   /*                                                                       */
 #define FT_CONFIG_OPTION_MAC_FONTS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Guessing methods to access embedded resource forks                    */
+  /*                                                                       */
+  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */
+  /*   GNU/Linux).                                                         */
+  /*                                                                       */
+  /*   Resource forks which include fonts data are stored sometimes in     */
+  /*   locations which users or developers don't expected.  In some cases, */
+  /*   resource forks start with some offset from the head of a file.  In  */
+  /*   other cases, the actual resource fork is stored in file different   */
+  /*   from what the user specifies.  If this option is activated,         */
+  /*   FreeType tries to guess whether such offsets or different file      */
+  /*   names must be used.                                                 */
+  /*                                                                       */
+  /*   Note that normal, direct access of resource forks is controlled via */
+  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */
+  /*                                                                       */
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
+#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
+#endif
 
 
   /*************************************************************************/
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -82,16 +82,18 @@
 
 #include <string.h>
 
-#define ft_strlen   strlen
+#define ft_memcmp   memcmp
+#define ft_memcpy   memcpy
+#define ft_memmove  memmove
+#define ft_memset   memset
 #define ft_strcat   strcat
 #define ft_strcmp   strcmp
-#define ft_strncmp  strncmp
-#define ft_memcpy   memcpy
 #define ft_strcpy   strcpy
+#define ft_strlen   strlen
+#define ft_strncmp  strncmp
 #define ft_strncpy  strncpy
-#define ft_memset   memset
-#define ft_memmove  memmove
-#define ft_memcmp   memcmp
+#define ft_strrchr  strrchr
+
 
 #include <stdio.h>
 
--- a/include/freetype/internal/ftdebug.h
+++ b/include/freetype/internal/ftdebug.h
@@ -141,7 +141,7 @@
   /*    debug level in your appliaciton.                                   */
   /*                                                                       */
   FT_EXPORT( const char * )
-  FT_Trace_Get_Name( FT_Int  index );
+  FT_Trace_Get_Name( FT_Int  idx );
 
 
   /*************************************************************************/
--- /dev/null
+++ b/include/freetype/internal/ftrfork.h
@@ -1,0 +1,184 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftrfork.h                                                              */
+/*                                                                         */
+/*    Embedded resource forks accessor (specification).                    */
+/*                                                                         */
+/*  Copyright 2004 by                                                      */
+/*  Masatake YAMATO and Redhat K.K.                                        */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of                      */
+/* Information-technology Promotion Agency, Japan.                         */
+/***************************************************************************/
+
+
+#ifndef __FTRFORK_H__
+#define __FTRFORK_H__
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_OBJECTS_H
+
+
+FT_BEGIN_HEADER
+
+
+  /* Number of guessing rules supported in `FT_Raccess_Guess'.            */
+  /* Don't forget to increment the number if you add a new guessing rule. */
+#define FT_RACCESS_N_RULES  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raccess_Guess                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Guess a file name and offset where the actual resource fork is     */
+  /*    stored.  The macro FT_RACCESS_N_RULES holds the number of          */
+  /*    guessing rules;  the guessed result for the Nth rule is            */
+  /*    represented as a triplet: a new file name (new_names[N]), a file   */
+  /*    offset (offsets[N]), and an error code (errors[N]).                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library ::                                                         */
+  /*      A FreeType library instance.                                     */
+  /*                                                                       */
+  /*    stream ::                                                          */
+  /*      A file stream containing the resource fork.                      */
+  /*                                                                       */
+  /*    base_name ::                                                       */
+  /*      The (base) file name of the resource fork used for some          */
+  /*      guessing rules.                                                  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    new_names ::                                                       */
+  /*      An array of guessed file names in which the resource forks may   */
+  /*      exist.  If `new_names[N]' is NULL, the guessed file name is      */
+  /*      equal to `base_name'.                                            */
+  /*                                                                       */
+  /*    offsets ::                                                         */
+  /*      An array of guessed file offsets.  `offsets[N]' holds the file   */
+  /*      offset of the possible start of the resource fork in file        */
+  /*      `new_names[N]'.                                                  */
+  /*                                                                       */
+  /*    errors ::                                                          */
+  /*      An array of FreeType error codes.  `errors[N]' is the error      */
+  /*      code of Nth guessing rule function.  If `errors[N]' is not       */
+  /*      FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless.      */
+  /*                                                                       */
+  FT_BASE( void )
+  FT_Raccess_Guess( FT_Library  library,
+                    FT_Stream   stream,
+                    char*       base_name,
+                    char**      new_names,
+                    FT_Long*    offsets,
+                    FT_Error*   errors );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raccess_Get_HeaderInfo                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the information from the header of resource fork.  The         */
+  /*    information includes the file offset where the resource map        */
+  /*    starts, and the file offset where the resource data starts.        */
+  /*    `FT_Raccess_Get_DataOffsets' requires these two data.              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library ::                                                         */
+  /*      A FreeType library instance.                                     */
+  /*                                                                       */
+  /*    stream ::                                                          */
+  /*      A file stream containing the resource fork.                      */
+  /*                                                                       */
+  /*    rfork_offset ::                                                    */
+  /*      The file offset where the resource fork starts.                  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    map_offset ::                                                      */
+  /*      The file offset where the resource map starts.                   */
+  /*                                                                       */
+  /*    rdata_pos ::                                                       */
+  /*      The file offset where the resource data starts.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  FT_Err_Ok means success.                     */
+  /*                                                                       */
+  FT_BASE( FT_Error )
+  FT_Raccess_Get_HeaderInfo( FT_Library  library,
+                             FT_Stream   stream,
+                             FT_Long     rfork_offset,
+                             FT_Long    *map_offset,
+                             FT_Long    *rdata_pos );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raccess_Get_DataOffsets                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the data offsets for a tag in a resource fork.  Offsets are    */
+  /*    stored in an array because, in some cases, resources in a resource */
+  /*    fork have the same tag.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library ::                                                         */
+  /*      A FreeType library instance.                                     */
+  /*                                                                       */
+  /*    stream ::                                                          */
+  /*      A file stream containing the resource fork.                      */
+  /*                                                                       */
+  /*    map_offset ::                                                      */
+  /*      The file offset where the resource map starts.                   */
+  /*                                                                       */
+  /*    rdata_pos ::                                                       */
+  /*      The file offset where the resource data starts.                  */
+  /*                                                                       */
+  /*    tag ::                                                             */
+  /*      The resource tag.                                                */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    offsets ::                                                         */
+  /*      The stream offsets for the resource data specified by `tag'.     */
+  /*      This array is allocated by the function, so you have to call     */
+  /*      @FT_Free after use.                                              */
+  /*                                                                       */
+  /*    count ::                                                           */
+  /*      The length of offsets array.                                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  FT_Err_Ok means success.                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Normally you should use `FT_Raccess_Get_HeaderInfo' to get the     */
+  /*    value for `map_offset' and `rdata_pos'.                            */
+  /*                                                                       */
+  FT_BASE( FT_Error )
+  FT_Raccess_Get_DataOffsets( FT_Library  library,
+                              FT_Stream   stream,
+                              FT_Long     map_offset,
+                              FT_Long     rdata_pos,
+                              FT_Long     tag,
+                              FT_Long   **offsets,
+                              FT_Long    *count );
+
+
+FT_END_HEADER
+
+#endif /* __FTRFORK_H__ */
+
+
+/* END */
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Stream handling (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2001, 2002, 2004 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -314,6 +314,17 @@
 
 #endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */
 
+
+  /* create a new (input) stream from an FT_Open_Args structure */
+  FT_BASE( FT_Error )
+  FT_Stream_New( FT_Library           library,
+                 const FT_Open_Args*  args,
+                 FT_Stream           *astream );
+
+  /* free a stream */
+  FT_BASE( void )
+  FT_Stream_Free( FT_Stream  stream,                    
+                  FT_Int     external );
 
   /* initialize a stream for reading in-memory data */
   FT_BASE( void )
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tracing handling (specification only).                               */
 /*                                                                         */
-/*  Copyright 2002 by                                                      */
+/*  Copyright 2002, 2004 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,12 +16,12 @@
 /***************************************************************************/
 
 
-/* definitions of trace levels for FreeType 2 */
+  /* definitions of trace levels for FreeType 2 */
 
-/* the first level must always be `trace_any' */
+  /* the first level must always be `trace_any' */
 FT_TRACE_DEF( any )
 
-/* base components */
+  /* base components */
 FT_TRACE_DEF( calc )      /* calculations            (ftcalc.c)   */
 FT_TRACE_DEF( memory )    /* memory manager          (ftobjs.c)   */
 FT_TRACE_DEF( stream )    /* stream manager          (ftstream.c) */
@@ -35,14 +35,15 @@
 FT_TRACE_DEF( raster )    /* monochrome rasterizer   (ftraster.c) */
 FT_TRACE_DEF( smooth )    /* anti-aliasing raster    (ftgrays.c)  */
 FT_TRACE_DEF( mm )        /* MM interface            (ftmm.c)     */
+FT_TRACE_DEF( raccess )   /* resource fork accessor  (ftrfork.c)  */
 
 /* Cache sub-system */
-FT_TRACE_DEF( cache )     /* cache sub-system        (ftcache.c, etc..) */
+FT_TRACE_DEF( cache )     /* cache sub-system        (ftcache.c, etc.) */
 
 /* SFNT driver components */
-FT_TRACE_DEF( sfobjs )    /*  SFNT object handler     (sfobjs.c)   */
-FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)    */
-FT_TRACE_DEF( ttload )    /* basic TrueType tables   (ttload.c)    */
+FT_TRACE_DEF( sfobjs )    /* SFNT object handler     (sfobjs.c)   */
+FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)   */
+FT_TRACE_DEF( ttload )    /* basic TrueType tables   (ttload.c)   */
 FT_TRACE_DEF( ttpost )    /* PS table processing     (ttpost.c)   */
 FT_TRACE_DEF( ttsbit )    /* TrueType sbit handling  (ttsbit.c)   */
 
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Internal header files (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -34,6 +34,7 @@
 #define FT_INTERNAL_GLYPH_LOADER_H        <freetype/internal/ftgloadr.h>
 #define FT_INTERNAL_SFNT_H                <freetype/internal/sfnt.h>
 #define FT_INTERNAL_SERVICE_H             <freetype/internal/ftserv.h>
+#define FT_INTERNAL_RFORK_H               <freetype/internal/ftrfork.h>
 
 #define FT_INTERNAL_TRUETYPE_TYPES_H      <freetype/internal/tttypes.h>
 #define FT_INTERNAL_TYPE1_TYPES_H         <freetype/internal/t1types.h>
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -1,4 +1,4 @@
-# FreeType 2 src/base Jamfile (c) 2001, 2002, 2003 David Turner
+# FreeType 2 src/base Jamfile (c) 2001, 2002, 2003, 2004 David Turner
 #
 
 SubDir  FT2_TOP $(FT2_SRC_DIR) base ;
@@ -10,7 +10,7 @@
   if $(FT2_MULTI)
   {
     _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln
-               ftobjs ftnames ;
+               ftobjs ftnames ftrfork ;
   }
   else
   {
@@ -24,8 +24,7 @@
 #
 Library  $(FT2_LIB) : ftsystem.c   ftinit.c    ftglyph.c  ftmm.c     ftbdf.c
                       ftbbox.c     ftdebug.c   ftxf86.c   fttype1.c  ftpfr.c
-                      ftstroke.c   ftwinfnt.c
-                      ;
+                      ftstroke.c   ftwinfnt.c ;
 
 # Add Macintosh-specific file to the library when necessary.
 #
--- a/src/base/ftbase.c
+++ b/src/base/ftbase.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component (body only).                         */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -29,6 +29,7 @@
 #include "ftgloadr.c"
 #include "ftobjs.c"
 #include "ftnames.c"
+#include "ftrfork.c"
 
 #if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON )
 #include "ftmac.c"
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -21,6 +21,7 @@
 #include FT_OUTLINE_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_RFORK_H
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_SFNT_H    /* for SFNT_Load_Table_Func */
 #include FT_TRUETYPE_TABLES_H
@@ -103,12 +104,12 @@
   /*************************************************************************/
 
 
-  /* create a new input stream from a FT_Open_Args structure */
-  /*                                                         */
-  static FT_Error
-  ft_input_stream_new( FT_Library           library,
-                       const FT_Open_Args*  args,
-                       FT_Stream*           astream )
+  /* create a new input stream from an FT_Open_Args structure */
+  /*                                                          */
+  FT_BASE_DEF( FT_Error )
+  FT_Stream_New( FT_Library           library,
+                 const FT_Open_Args*  args,
+                 FT_Stream           *astream )
   {
     FT_Error   error;
     FT_Memory  memory;
@@ -166,9 +167,9 @@
   }
 
 
-  static void
-  ft_input_stream_free( FT_Stream  stream,
-                        FT_Int     external )
+  FT_BASE_DEF( void )
+  FT_Stream_Free( FT_Stream  stream,
+                  FT_Int     external )
   {
     if ( stream )
     {
@@ -722,13 +723,13 @@
 
     /* discard charmaps */
     destroy_charmaps( face, memory );
-    
+
     /* finalize format-specific stuff */
     if ( clazz->done_face )
       clazz->done_face( face );
 
     /* close the stream for this face if needed */
-    ft_input_stream_free(
+    FT_Stream_Free(
       face->stream,
       ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
 
@@ -1133,9 +1134,8 @@
   static FT_Error
   Mac_Read_POST_Resource( FT_Library  library,
                           FT_Stream   stream,
-                          FT_Long     resource_listoffset,
+                          FT_Long    *offsets,
                           FT_Long     resource_cnt,
-                          FT_Long     resource_data,
                           FT_Long     face_index,
                           FT_Face    *aface )
   {
@@ -1146,7 +1146,6 @@
     FT_Long    len;
     FT_Long    pfb_len, pfb_pos, pfb_lenpos;
     FT_Long    rlen, temp;
-    FT_Long   *offsets;
 
 
     if ( face_index == -1 )
@@ -1154,23 +1153,6 @@
     if ( face_index != 0 )
       return error;
 
-    if ( FT_ALLOC( offsets, (FT_Long)resource_cnt * sizeof ( FT_Long ) ) )
-      return error;
-
-    error = FT_Stream_Seek( stream, resource_listoffset );
-    if ( error )
-      goto Exit;
-
-    /* Find all the POST resource offsets */
-    for ( i = 0; i < resource_cnt; ++i )
-    {
-      (void)FT_STREAM_SKIP( 4 );    /* resource id and resource name */
-      if ( FT_READ_LONG( temp ) )
-        goto Exit;
-      offsets[i] = resource_data + ( temp & 0xFFFFFFL );
-      (void)FT_STREAM_SKIP( 4 );    /* mbz */
-    }
-
     /* Find the length of all the POST resources, concatenated.  Assume */
     /* worst case (each resource in its own section).                   */
     pfb_len = 0;
@@ -1256,7 +1238,6 @@
     FT_FREE( pfb_data );
 
   Exit:
-    FT_FREE( offsets );
     return error;
   }
 
@@ -1269,9 +1250,8 @@
   static FT_Error
   Mac_Read_sfnt_Resource( FT_Library  library,
                           FT_Stream   stream,
-                          FT_Long     resource_listoffset,
+                          FT_Long    *offsets,
                           FT_Long     resource_cnt,
-                          FT_Long     resource_data,
                           FT_Long     face_index,
                           FT_Face    *aface )
   {
@@ -1278,8 +1258,7 @@
     FT_Memory  memory = library->memory;
     FT_Byte*   sfnt_data;
     FT_Error   error;
-    int        i;
-    FT_Long    flag_offset= 0xFFFFFFL;
+    FT_Long    flag_offset;
     FT_Long    rlen;
     int        is_cff;
 
@@ -1289,25 +1268,11 @@
     if ( face_index >= resource_cnt )
       return FT_Err_Cannot_Open_Resource;
 
-    error = FT_Stream_Seek( stream, resource_listoffset );
+    flag_offset = offsets[face_index];
+    error = FT_Stream_Seek( stream, flag_offset );
     if ( error )
       goto Exit;
 
-    for ( i = 0; i <= face_index; ++i )
-    {
-      (void)FT_STREAM_SKIP( 4 );    /* resource id and resource name */
-      if ( FT_READ_LONG( flag_offset ) )
-        goto Exit;
-      flag_offset &= 0xFFFFFFL;
-      (void)FT_STREAM_SKIP( 4 );    /* mbz */
-    }
-
-    if ( flag_offset == 0xFFFFFFL )
-      return FT_Err_Cannot_Open_Resource;
-
-    error = FT_Stream_Seek( stream, flag_offset + resource_data );
-    if ( error )
-      goto Exit;
     if ( FT_READ_LONG( rlen ) )
       goto Exit;
     if ( rlen == -1 )
@@ -1348,110 +1313,41 @@
                  FT_Long     face_index,
                  FT_Face    *aface )
   {
-    FT_Error       error;
-    unsigned char  head[16], head2[16];
-    FT_Long        rdata_pos, map_pos, rdata_len;
-    int            allzeros, allmatch, i, cnt, subcnt;
-    FT_Long        type_list, rpos;
-    FT_ULong       tag;
+    FT_Memory  memory = library->memory;
+    FT_Error   error;
+    FT_Long    map_offset, rdara_pos;
+    FT_Long    *data_offsets;
+    FT_Long    count;
 
 
-    error = FT_Stream_Seek( stream, resource_offset );
+    error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
+                                       &map_offset, &rdara_pos );
     if ( error )
-      goto Exit;
-    error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
-    if ( error )
-      goto Exit;
+      return error;
 
-    rdata_pos = resource_offset + ( ( head[0] << 24 ) |
-                                    ( head[1] << 16 ) |
-                                    ( head[2] <<  8 ) |
-                                      head[3]         );
-    map_pos   = resource_offset + ( ( head[4] << 24 ) |
-                                    ( head[5] << 16 ) |
-                                    ( head[6] <<  8 ) |
-                                      head[7]         );
-    rdata_len = ( head[ 8] << 24 ) |
-                ( head[ 9] << 16 ) |
-                ( head[10] <<  8 ) |
-                  head[11];
-    /* map_len = head[12] .. head[15] */
-
-    if ( rdata_pos + rdata_len != map_pos || map_pos == resource_offset )
-      return FT_Err_Unknown_File_Format;
-
-    error = FT_Stream_Seek( stream, map_pos );
-    if ( error )
-      goto Exit;
-
-    head2[15] = (FT_Byte)( head[15] + 1 );     /* make it be different */
-
-    error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
-    if ( error )
-      goto Exit;
-
-    allzeros = 1;
-    allmatch = 1;
-    for ( i = 0; i < 16; ++i )
+    error = FT_Raccess_Get_DataOffsets( library, stream,
+                                        map_offset, rdara_pos,
+                                        FT_MAKE_TAG( 'P', 'O', 'S', 'T' ),
+                                        &data_offsets, &count );
+    if ( !error )
     {
-      if ( head2[i] != 0 )
-        allzeros = 0;
-      if ( head2[i] != head[i] )
-        allmatch = 0;
+      error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
+                                      face_index, aface );
+      FT_FREE( data_offsets );
+      return error;
     }
-    if ( !allzeros && !allmatch )
-      return FT_Err_Unknown_File_Format;
 
-    /* If we've gotten this far then it's probably a mac resource file. */
-    /* Now, does it contain any interesting resources?                  */
-
-    /* Skip handle to next resource map, the file resource number, and  */
-    /* attributes.                                                      */
-    (void)FT_STREAM_SKIP( 4 + 2 + 2 );
-
-    if ( FT_READ_USHORT( type_list ) )
-      goto Exit;
-    if ( type_list == -1 )
-      return FT_Err_Unknown_File_Format;
-
-    error = FT_Stream_Seek( stream, map_pos + type_list );
-    if ( error )
-      goto Exit;
-
-    if ( FT_READ_USHORT( cnt ) )
-      goto Exit;
-
-    ++cnt;
-    for ( i = 0; i < cnt; ++i )
+    error = FT_Raccess_Get_DataOffsets( library, stream,
+                                        map_offset, rdara_pos,
+                                        FT_MAKE_TAG( 's', 'f', 'n', 't' ),
+                                        &data_offsets, &count );
+    if ( !error )
     {
-      if ( FT_READ_LONG( tag )      ||
-           FT_READ_USHORT( subcnt ) ||
-           FT_READ_USHORT( rpos )   )
-        goto Exit;
-
-      ++subcnt;
-      rpos += map_pos + type_list;
-      if ( tag == FT_MAKE_TAG( 'P', 'O', 'S', 'T' ) )
-        return Mac_Read_POST_Resource( library,
-                                       stream,
-                                       rpos,
-                                       subcnt,
-                                       rdata_pos,
-                                       face_index,
-                                       aface );
-      else if ( tag == FT_MAKE_TAG( 's', 'f', 'n', 't' ) )
-        return Mac_Read_sfnt_Resource( library,
-                                       stream,
-                                       rpos,
-                                       subcnt,
-                                       rdata_pos,
-                                       face_index,
-                                       aface );
+      error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
+                                      face_index, aface );
+      FT_FREE( data_offsets );
     }
 
-    error = FT_Err_Cannot_Open_Resource; /* this file contains no
-                                            interesting resources */
-  Exit:
     return error;
   }
 
@@ -1506,11 +1402,87 @@
   }
 
 
-  /* Check for some macintosh formats                              */
+  static FT_Error
+  load_face_in_embedded_rfork( FT_Library           library,
+                               FT_Stream            stream,
+                               FT_Long              face_index,
+                               FT_Face             *aface,
+                               const FT_Open_Args  *args )
+  {
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_raccess
+
+    FT_Memory  memory = library->memory;
+    FT_Error   error  = FT_Err_Unknown_File_Format;
+    int        i;
+
+    char *     file_names[FT_RACCESS_N_RULES];
+    FT_Long    offsets[FT_RACCESS_N_RULES];
+    FT_Error   errors[FT_RACCESS_N_RULES];
+
+    FT_Open_Args  args2;
+    FT_Stream     stream2;
+
+
+    FT_Raccess_Guess( library, stream,
+                      args->pathname, file_names, offsets, errors );
+
+    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
+    {
+      if ( errors[i] )
+      {
+        FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
+        continue;
+      }
+
+      args2.flags    = FT_OPEN_PATHNAME;
+      args2.pathname = file_names[i] ? file_names[i] : args->pathname;
+
+      FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
+                  i, args2.pathname, offsets[i] ));
+
+      error = FT_Stream_New( library, &args2, &stream2 );
+      if ( error )
+      {
+        FT_TRACE3(( "failed\n" ));
+        continue;
+      }
+
+      error = IsMacResource( library, stream2, offsets[i],
+                             face_index, aface );
+      FT_Stream_Close( stream2 );
+
+      FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
+
+      if ( !error )
+          break;
+    }
+
+    for (i = 0; i < FT_RACCESS_N_RULES; i++)
+    {
+      if ( file_names[i] )
+        FT_FREE( file_names[i] );
+    }
+
+    /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
+    if ( error )
+      error = FT_Err_Unknown_File_Format;
+
+    return error;
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_objs
+
+  }
+
+
+  /* Check for some macintosh formats.                             */
   /* Is this a macbinary file?  If so look at the resource fork.   */
   /* Is this a mac dfont file?                                     */
   /* Is this an old style resource fork? (in data)                 */
-  /* Else if we're on Mac OS/X, open the resource fork explicitly. */
+  /* Else call load_face_in_embedded_rfork to try extra rules      */
+  /* (defined in `ftrfork.c').                                     */
   /*                                                               */
   static FT_Error
   load_mac_face( FT_Library           library,
@@ -1525,41 +1497,27 @@
 
     error = IsMacBinary( library, stream, face_index, aface );
     if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
-      error = IsMacResource( library, stream, 0, face_index, aface );
-
-    /* Only meaningful on sytems with hfs+ drivers (or Macs) */
-
-    if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format      ||
-           FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation )  &&
-           ( args->flags & FT_OPEN_PATHNAME )                           )
     {
-      FT_Open_Args  args2;
-      char*         newpath;
-      FT_Memory     memory;
-      FT_Stream     stream2;
 
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_raccess
 
-      memory = library->memory;
+      FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));
 
-      if ( FT_ALLOC( newpath,
-                     ft_strlen( args->pathname ) + ft_strlen( "/rsrc" ) + 1 ) )
-        goto Fail;
+      error = IsMacResource( library, stream, 0, face_index, aface );
 
-      ft_strcpy( newpath, args->pathname );
-      ft_strcat( newpath, "/rsrc" );
+      FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
 
-      args2.flags    = FT_OPEN_PATHNAME;
-      args2.pathname = (char*)newpath;
-      error = ft_input_stream_new( library, &args2, &stream2 );
-      if ( !error )
-      {
-        error = IsMacResource( library, stream2, 0, face_index, aface );
-        FT_Stream_Close( stream2 );
-      }
-      FT_FREE( newpath );
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_objs
+
     }
 
-  Fail:
+    if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format      ||
+           FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
+         ( args->flags & FT_OPEN_PATHNAME )                            )
+      error = load_face_in_embedded_rfork( library, stream,
+                                           face_index, aface, args );
     return error;
   }
 
@@ -1584,7 +1542,7 @@
 
 
     /* test for valid `library' delayed to */
-    /* ft_input_stream_new()               */
+    /* FT_Stream_New()                     */
 
     if ( !aface || !args )
       return FT_Err_Invalid_Argument;
@@ -1595,7 +1553,7 @@
                                args->stream                     );
 
     /* create input stream */
-    error = ft_input_stream_new( library, args, &stream );
+    error = FT_Stream_New( library, args, &stream );
     if ( error )
       goto Exit;
 
@@ -1628,7 +1586,7 @@
       else
         error = FT_Err_Invalid_Handle;
 
-      ft_input_stream_free( stream, external_stream );
+      FT_Stream_Free( stream, external_stream );
       goto Fail;
     }
     else
@@ -1682,7 +1640,7 @@
       /* stream (we opened a different stream which extracted the       */
       /* interesting information out of this stream here.  That stream  */
       /* will still be open and the face will point to it).             */
-      ft_input_stream_free( stream, external_stream );
+      FT_Stream_Free( stream, external_stream );
       return error;
     }
 
@@ -1694,7 +1652,7 @@
       error = FT_Err_Unknown_File_Format;
 
   Fail2:
-      ft_input_stream_free( stream, external_stream );
+      FT_Stream_Free( stream, external_stream );
       goto Fail;
     }
 
@@ -1803,7 +1761,7 @@
     FT_Driver_Class  clazz;
 
 
-    /* test for valid `parameters' delayed to ft_input_stream_new() */
+    /* test for valid `parameters' delayed to FT_Stream_New() */
 
     if ( !face )
       return FT_Err_Invalid_Face_Handle;
@@ -1812,7 +1770,7 @@
     if ( !driver )
       return FT_Err_Invalid_Driver_Handle;
 
-    error = ft_input_stream_new( driver->root.library, parameters, &stream );
+    error = FT_Stream_New( driver->root.library, parameters, &stream );
     if ( error )
       goto Exit;
 
@@ -1825,7 +1783,7 @@
       error = clazz->attach_file( face, stream );
 
     /* close the attached stream */
-    ft_input_stream_free( stream,
+    FT_Stream_Free( stream,
                     (FT_Bool)( parameters->stream &&
                                ( parameters->flags & FT_OPEN_STREAM ) ) );
 
--- /dev/null
+++ b/src/base/ftrfork.c
@@ -1,0 +1,717 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftrfork.c                                                              */
+/*                                                                         */
+/*    Embedded resource forks accessor (body).                             */
+/*                                                                         */
+/*  Copyright 2004 by                                                      */
+/*  Masatake YAMATO and Redhat K.K.                                        */
+/*                                                                         */
+/*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */
+/*  derived from ftobjs.c.                                                 */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/* Development of the code in this file is support of                      */
+/* Information-technology Promotion Agency, Japan.                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_RFORK_H
+
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_raccess
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****               Resource fork directory access                    ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  FT_BASE_DEF( FT_Error )
+  FT_Raccess_Get_HeaderInfo( FT_Library  library,
+                             FT_Stream   stream,
+                             FT_Long     rfork_offset,
+                             FT_Long    *map_offset,
+                             FT_Long    *rdata_pos )
+  {
+    FT_Error       error;
+    unsigned char  head[16], head2[16];
+    FT_Long        map_pos, rdata_len;
+    int            allzeros, allmatch, i;
+    FT_Long        type_list;
+
+    FT_UNUSED( library );
+
+
+    error = FT_Stream_Seek( stream, rfork_offset );
+    if ( error )
+      return error;
+
+    error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
+    if ( error )
+      return error;
+
+    *rdata_pos = rfork_offset + ( ( head[0] << 24 ) |
+                                  ( head[1] << 16 ) |
+                                  ( head[2] <<  8 ) |
+                                    head[3]         );
+    map_pos    = rfork_offset + ( ( head[4] << 24 ) |
+                                  ( head[5] << 16 ) |
+                                  ( head[6] <<  8 ) |
+                                    head[7]         );
+    rdata_len = ( head[ 8] << 24 ) |
+                ( head[ 9] << 16 ) |
+                ( head[10] <<  8 ) |
+                  head[11];
+
+    /* map_len = head[12] .. head[15] */
+
+    if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )
+      return FT_Err_Unknown_File_Format;
+
+    error = FT_Stream_Seek( stream, map_pos );
+    if ( error )
+      return error;
+
+    head2[15] = (FT_Byte)( head[15] + 1 );       /* make it be different */
+
+    error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
+    if ( error )
+      return error;
+
+    allzeros = 1;
+    allmatch = 1;
+    for ( i = 0; i < 16; ++i )
+    {
+      if ( head2[i] != 0 )
+        allzeros = 0;
+      if ( head2[i] != head[i] )
+        allmatch = 0;
+    }
+    if ( !allzeros && !allmatch )
+      return FT_Err_Unknown_File_Format;
+
+    /* If we have reached this point then it is probably a mac resource */
+    /* file.  Now, does it contain any interesting resources?           */
+    /* Skip handle to next resource map, the file resource number, and  */
+    /* attributes.                                                      */
+    (void)FT_STREAM_SKIP( 4        /* skip handle to next resource map */
+                          + 2      /* skip file resource number */
+                          + 2 );   /* skip attributes */
+
+    if ( FT_READ_USHORT( type_list ) )
+      return error;
+    if ( type_list == -1 )
+      return FT_Err_Unknown_File_Format;
+
+    error = FT_Stream_Seek( stream, map_pos + type_list );
+    if ( error )
+      return error;
+
+    *map_offset = map_pos + type_list;
+    return FT_Err_Ok;
+  }
+
+
+  FT_BASE_DEF( FT_Error )
+  FT_Raccess_Get_DataOffsets( FT_Library  library,
+                              FT_Stream   stream,
+                              FT_Long     map_offset,
+                              FT_Long     rdata_pos,
+                              FT_Long     tag,
+                              FT_Long   **offsets,
+                              FT_Long    *count )
+  {
+    FT_Error   error;
+    int        i, j, cnt, subcnt;
+    FT_Long    tag_internal, rpos;
+    FT_Memory  memory = library->memory;
+    FT_Long    temp;
+    FT_Long    *offsets_internal;
+
+
+    error = FT_Stream_Seek( stream, map_offset );
+    if ( error )
+      return error;
+
+    if ( FT_READ_USHORT( cnt ) )
+      return error;
+    cnt++;
+
+    for ( i = 0; i < cnt; ++i )
+    {
+      if ( FT_READ_LONG( tag_internal ) ||
+           FT_READ_USHORT( subcnt )     ||
+           FT_READ_USHORT( rpos )       )
+        return error;
+
+      FT_TRACE2(( "Resource tags: %c%c%c%c\n",
+                  (char)( 0xff & ( tag_internal >> 24 ) ),
+                  (char)( 0xff & ( tag_internal >> 16 ) ),
+                  (char)( 0xff & ( tag_internal >>  8 ) ),
+                  (char)( 0xff & ( tag_internal >>  0 ) ) ));
+
+      if ( tag_internal == tag )
+      {
+        *count = subcnt + 1;
+        rpos  += map_offset;
+
+        error = FT_Stream_Seek( stream, rpos );
+        if ( error )
+          return error;
+
+        if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) )
+          return error;
+
+        for ( j = 0; j < *count; ++j )
+        {
+          (void)FT_STREAM_SKIP( 2 ); /* resource id */
+          (void)FT_STREAM_SKIP( 2 ); /* rsource name */
+
+          if ( FT_READ_LONG( temp ) )
+          {
+            FT_FREE( offsets_internal );
+            return error;
+          }
+
+          offsets_internal[j] = rdata_pos + ( temp & 0xFFFFFFL );
+
+          (void)FT_STREAM_SKIP( 4 ); /* mbz */
+        }
+
+        *offsets = offsets_internal;
+
+        return FT_Err_Ok;
+      }
+    }
+
+    return FT_Err_Cannot_Open_Resource;
+  }
+
+
+#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                     Guessing functions                          ****/
+  /****                                                                 ****/
+  /****            When you add a new guessing function,                ****/
+  /****           update FT_RACCESS_N_RULES in ftrfork.h.               ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef FT_Error
+  (*raccess_guess_func)( FT_Library  library,
+                         FT_Stream   stream,
+                         char *      base_file_name,
+                         char      **result_file_name,
+                         FT_Long    *result_offset );
+
+
+  static FT_Error
+  raccess_guess_apple_double( FT_Library  library,
+                              FT_Stream   stream,
+                              char *      base_file_name,
+                              char      **result_file_name,
+                              FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_apple_single( FT_Library  library,
+                              FT_Stream   stream,
+                              char *      base_file_name,
+                              char      **result_file_name,
+                              FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_darwin_ufs_export( FT_Library  library,
+                                   FT_Stream   stream,
+                                   char *      base_file_name,
+                                   char      **result_file_name,
+                                   FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_darwin_hfsplus( FT_Library  library,
+                                FT_Stream   stream,
+                                char *      base_file_name,
+                                char      **result_file_name,
+                                FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_vfat( FT_Library  library,
+                      FT_Stream   stream,
+                      char *      base_file_name,
+                      char      **result_file_name,
+                      FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_linux_cap( FT_Library  library,
+                           FT_Stream   stream,
+                           char *      base_file_name,
+                           char      **result_file_name,
+                           FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_linux_double( FT_Library  library,
+                              FT_Stream   stream,
+                              char *      base_file_name,
+                              char      **result_file_name,
+                              FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_linux_netatalk( FT_Library  library,
+                                FT_Stream   stream,
+                                char *      base_file_name,
+                                char      **result_file_name,
+                                FT_Long    *result_offset );
+
+
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                       Helper functions                          ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+
+  static FT_Error
+  raccess_guess_apple_generic( FT_Library  library,
+                               FT_Stream   stream,
+                               char *      base_file_name,
+                               FT_Int32    magic,
+                               FT_Long    *result_offset );
+
+  static FT_Error
+  raccess_guess_linux_double_from_file_name( FT_Library  library,
+                                             char *      file_name,
+                                             FT_Long    *result_offset );
+
+  static char *
+  raccess_make_file_name( FT_Memory    memory,
+                          const char  *original_name,
+                          const char  *insertion );
+
+
+  FT_BASE_DEF( void )
+  FT_Raccess_Guess( FT_Library  library,
+                    FT_Stream   stream,
+                    char*       base_name,
+                    char      **new_names,
+                    FT_Long    *offsets,
+                    FT_Error   *errors )
+  {
+    FT_Long  i;
+
+
+    raccess_guess_func  funcs[FT_RACCESS_N_RULES] =
+    {
+      raccess_guess_apple_double,
+      raccess_guess_apple_single,
+      raccess_guess_darwin_ufs_export,
+      raccess_guess_darwin_hfsplus,
+      raccess_guess_vfat,
+      raccess_guess_linux_cap,
+      raccess_guess_linux_double,
+      raccess_guess_linux_netatalk,
+    };
+
+    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
+    {
+      new_names[i] = NULL;
+      errors[i] = FT_Stream_Seek( stream, 0 );
+      if ( errors[i] )
+        continue ;
+
+      errors[i] = (funcs[i])( library, stream, base_name,
+                              &(new_names[i]), &(offsets[i]) );
+    }
+
+    return;
+  }
+
+
+  static FT_Error
+  raccess_guess_apple_double( FT_Library  library,
+                              FT_Stream   stream,
+                              char *      base_file_name,
+                              char      **result_file_name,
+                              FT_Long    *result_offset )
+  {
+    FT_Int32  magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 );
+
+
+    *result_file_name = NULL;
+    return raccess_guess_apple_generic( library, stream, base_file_name,
+                                        magic, result_offset );
+  }
+
+
+  static FT_Error
+  raccess_guess_apple_single( FT_Library  library,
+                              FT_Stream   stream,
+                              char *      base_file_name,
+                              char      **result_file_name,
+                              FT_Long    *result_offset )
+  {
+    FT_Int32  magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00);
+
+
+    *result_file_name = NULL;
+    return raccess_guess_apple_generic( library, stream, base_file_name,
+                                        magic, result_offset );
+  }
+
+
+  static FT_Error
+  raccess_guess_darwin_ufs_export( FT_Library  library,
+                                   FT_Stream   stream,
+                                   char *      base_file_name,
+                                   char      **result_file_name,
+                                   FT_Long    *result_offset )
+  {
+    char*      newpath;
+    FT_Error   error;
+    FT_Memory  memory;
+
+    FT_UNUSED( stream );
+
+
+    memory  = library->memory;
+    newpath = raccess_make_file_name( memory, base_file_name, "._" );
+    if ( !newpath )
+      return FT_Err_Out_Of_Memory;
+
+    error = raccess_guess_linux_double_from_file_name( library, newpath,
+                                                       result_offset );
+    if ( !error )
+      *result_file_name = newpath;
+    else
+      FT_FREE( newpath );
+
+    return error;
+  }
+
+
+  static FT_Error
+  raccess_guess_darwin_hfsplus( FT_Library  library,
+                                FT_Stream   stream,
+                                char *      base_file_name,
+                                char      **result_file_name,
+                                FT_Long    *result_offset )
+  {
+    /*
+      Only meaningful on systems with hfs+ drivers (or Macs).
+     */
+    FT_Error   error;
+    char*      newpath;
+    FT_Memory  memory;
+
+    FT_UNUSED( stream );
+
+
+    memory = library->memory;
+
+    if ( FT_ALLOC( newpath,
+                   ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) )
+      return error;
+
+    ft_strcpy( newpath, base_file_name );
+    ft_strcat( newpath, "/rsrc" );
+    *result_file_name = newpath;
+    *result_offset = 0;
+    return FT_Err_Ok;
+  }
+
+
+  static FT_Error
+  raccess_guess_vfat( FT_Library  library,
+                      FT_Stream   stream,
+                      char *      base_file_name,
+                      char      **result_file_name,
+                      FT_Long    *result_offset )
+  {
+    char*      newpath;
+    FT_Memory  memory;
+
+    FT_UNUSED( stream );
+
+
+    memory = library->memory;
+
+    newpath = raccess_make_file_name( memory, base_file_name,
+                                      "resource.frk/" );
+    if ( !newpath )
+      return FT_Err_Out_Of_Memory;
+
+    *result_file_name = newpath;
+    *result_offset    = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+  static FT_Error
+  raccess_guess_linux_cap( FT_Library  library,
+                           FT_Stream   stream,
+                           char *      base_file_name,
+                           char      **result_file_name,
+                           FT_Long    *result_offset )
+  {
+    char*      newpath;
+    FT_Memory  memory;
+
+    FT_UNUSED( stream );
+
+
+    memory = library->memory;
+
+    newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
+    if ( !newpath )
+      return FT_Err_Out_Of_Memory;
+
+    *result_file_name = newpath;
+    *result_offset    = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+  static FT_Error
+  raccess_guess_linux_double( FT_Library  library,
+                              FT_Stream   stream,
+                              char *      base_file_name,
+                              char      **result_file_name,
+                              FT_Long    *result_offset )
+  {
+    char*      newpath;
+    FT_Error   error;
+    FT_Memory  memory;
+
+    FT_UNUSED( stream );
+
+
+    memory = library->memory;
+
+    newpath = raccess_make_file_name( memory, base_file_name, "%" );
+    if ( !newpath )
+      return FT_Err_Out_Of_Memory;
+
+    error = raccess_guess_linux_double_from_file_name( library, newpath,
+                                                       result_offset );
+    if ( !error )
+      *result_file_name = newpath;
+    else
+      FT_FREE( newpath );
+
+    return error;
+  }
+
+
+  static FT_Error
+  raccess_guess_linux_netatalk( FT_Library  library,
+                                FT_Stream   stream,
+                                char *      base_file_name,
+                                char      **result_file_name,
+                                FT_Long    *result_offset )
+  {
+    char*      newpath;
+    FT_Error   error;
+    FT_Memory  memory;
+
+    FT_UNUSED( stream );
+
+
+    memory = library->memory;
+
+    newpath = raccess_make_file_name( memory, base_file_name,
+                                      ".AppleDouble/" );
+    if ( !newpath )
+      return FT_Err_Out_Of_Memory;
+
+    error = raccess_guess_linux_double_from_file_name( library, newpath,
+                                                       result_offset );
+    if ( !error )
+      *result_file_name = newpath;
+    else
+      FT_FREE( newpath );
+
+    return error;
+  }
+
+
+  static FT_Error
+  raccess_guess_apple_generic( FT_Library  library,
+                               FT_Stream   stream,
+                               char *      base_file_name,
+                               FT_Int32    magic,
+                               FT_Long    *result_offset )
+  {
+    FT_Int32   magic_from_stream;
+    FT_Error   error;
+    FT_Int32   version_number;
+    FT_UShort  n_of_entries;
+
+    int        i;
+    FT_UInt32  entry_id, entry_offset, entry_length;
+
+    const FT_UInt32  resource_fork_entry_id = 0x2;
+
+    FT_UNUSED( library );
+    FT_UNUSED( base_file_name );
+
+
+    if ( FT_READ_LONG ( magic_from_stream ) )
+      return error;
+    if ( magic_from_stream != magic )
+      return FT_Err_Unknown_File_Format;
+
+    if ( FT_READ_LONG( version_number ) )
+      return error;
+
+    /* filler */
+    error = FT_Stream_Skip( stream, 16 );
+    if ( error )
+      return error;
+
+    if ( FT_READ_USHORT( n_of_entries ) )
+      return error;
+    if ( n_of_entries == 0 )
+      return FT_Err_Unknown_File_Format;
+
+    for ( i = 0; i < n_of_entries; i++ )
+    {
+      if ( FT_READ_LONG( entry_id ) )
+        return error;
+      if ( entry_id == resource_fork_entry_id )
+      {
+        if ( FT_READ_LONG( entry_offset ) ||
+             FT_READ_LONG( entry_length ) )
+          continue;
+        *result_offset = entry_offset;
+
+        return FT_Err_Ok;
+      }
+      else
+        FT_Stream_Skip( stream, 4 + 4 );    /* offset + length */
+      }
+
+    return FT_Err_Unknown_File_Format;
+  }
+
+
+  static FT_Error
+  raccess_guess_linux_double_from_file_name( FT_Library  library,
+                                             char *      file_name,
+                                             FT_Long    *result_offset )
+  {
+    FT_Memory     memory;
+    FT_Open_Args  args2;
+    FT_Stream     stream2;
+    char *        nouse = NULL;
+    FT_Error      error;
+
+
+    memory = library->memory;
+
+    args2.flags    = FT_OPEN_PATHNAME;
+    args2.pathname = file_name;
+    error = FT_Stream_New( library, &args2, &stream2 );
+    if ( error )
+      return error;
+
+    error = raccess_guess_apple_double( library, stream2, file_name,
+                                        &nouse, result_offset );
+
+    FT_Stream_Close( stream2 );
+
+    return error;
+  }
+
+
+  static char*
+  raccess_make_file_name( FT_Memory    memory,
+                          const char  *original_name,
+                          const char  *insertion )
+  {
+    char*        new_name;
+    char*        tmp;
+    const char*  slash;
+    unsigned     new_length;
+    FT_ULong     error;
+
+    new_length = ft_strlen( original_name ) + ft_strlen( insertion );
+    if ( FT_ALLOC( new_name, new_length + 1 ) )
+      return NULL;
+
+    tmp = ft_strrchr( original_name, '/' );
+    if ( tmp )
+    {
+      ft_strncpy( new_name, original_name, tmp - original_name + 1 );
+      new_name[tmp - original_name + 1] = '\0';
+      slash = tmp + 1;
+    }
+    else
+    {
+      slash       = original_name;
+      new_name[0] = '\0';
+    }
+
+    ft_strcat( new_name, insertion );
+    ft_strcat( new_name, slash );
+
+    return new_name;
+  }
+
+
+#else   /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
+
+
+  /*************************************************************************/
+  /*                  Dummy function; just sets errors                     */
+  /*************************************************************************/
+
+  FT_BASE_DEF( void )
+  FT_Raccess_Guess( FT_Library  library,
+                    FT_Stream   stream,
+                    char*       base_name,
+                    char      **new_names,
+                    FT_Long    *offsets,
+                    FT_Error   *errors )
+  {
+    int  i;
+
+
+    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
+    {
+      new_names[i] = NULL;
+      offsets[i]   = 0;
+      errors[i]    = FT_Err_Unimplemented_Feature;
+    }
+  }
+
+
+#endif  /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
+
+
+/* END */
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 1996-2000, 2002, 2003 by
+# Copyright 1996-2000, 2002, 2003, 2004 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -32,16 +32,17 @@
 #
 #   ftsystem, ftinit, and ftdebug are handled by freetype.mk
 #
-BASE_SRC := $(BASE_DIR)/ftcalc.c   \
-            $(BASE_DIR)/fttrigon.c \
-            $(BASE_DIR)/ftutil.c   \
-            $(BASE_DIR)/ftstream.c \
+BASE_SRC := $(BASE_DIR)/ftapi.c    \
+            $(BASE_DIR)/ftcalc.c   \
+            $(BASE_DIR)/ftdbgmem.c \
             $(BASE_DIR)/ftgloadr.c \
-            $(BASE_DIR)/ftoutln.c  \
-            $(BASE_DIR)/ftobjs.c   \
-            $(BASE_DIR)/ftapi.c    \
             $(BASE_DIR)/ftnames.c  \
-            $(BASE_DIR)/ftdbgmem.c
+            $(BASE_DIR)/ftobjs.c   \
+            $(BASE_DIR)/ftoutln.c  \
+            $(BASE_DIR)/ftrfork.c  \
+            $(BASE_DIR)/ftstream.c \
+            $(BASE_DIR)/fttrigon.c \
+            $(BASE_DIR)/ftutil.c
 
 # Base layer `extensions' sources
 #
@@ -49,15 +50,15 @@
 # object.  It will then be linked to the final executable only if one of its
 # symbols is used by the application.
 #
-BASE_EXT_SRC := $(BASE_DIR)/ftglyph.c  \
-                $(BASE_DIR)/ftmm.c     \
+BASE_EXT_SRC := $(BASE_DIR)/ftbbox.c   \
                 $(BASE_DIR)/ftbdf.c    \
-                $(BASE_DIR)/fttype1.c  \
-                $(BASE_DIR)/ftxf86.c   \
+                $(BASE_DIR)/ftglyph.c  \
+                $(BASE_DIR)/ftmm.c     \
                 $(BASE_DIR)/ftpfr.c    \
                 $(BASE_DIR)/ftstroke.c \
+                $(BASE_DIR)/fttype1.c  \
                 $(BASE_DIR)/ftwinfnt.c \
-                $(BASE_DIR)/ftbbox.c
+                $(BASE_DIR)/ftxf86.c
 
 # Default extensions objects
 #