From 754353343ecd27582ed86cd9fd07d31ab1df883c Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 25 Feb 2004 12:58:54 +0000 Subject: [PATCH] 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. --- ChangeLog | 40 ++ devel/ftoption.h | 25 +- include/freetype/config/ftoption.h | 25 +- include/freetype/config/ftstdlib.h | 14 +- include/freetype/internal/ftdebug.h | 2 +- include/freetype/internal/ftrfork.h | 184 +++++++ include/freetype/internal/ftstream.h | 13 +- include/freetype/internal/fttrace.h | 17 +- include/freetype/internal/internal.h | 3 +- src/base/Jamfile | 7 +- src/base/ftbase.c | 3 +- src/base/ftobjs.c | 334 ++++++------- src/base/ftrfork.c | 717 +++++++++++++++++++++++++++ src/base/rules.mk | 29 +- 14 files changed, 1187 insertions(+), 226 deletions(-) create mode 100644 include/freetype/internal/ftrfork.h create mode 100644 src/base/ftrfork.c diff --git a/ChangeLog b/ChangeLog index cb47d95ce..eb598ab82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2004-02-17 Masatake YAMATO + + 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 * docs/CHANGES: Updated. diff --git a/devel/ftoption.h b/devel/ftoption.h index 3ba11bfae..b6afbb634 100644 --- 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, */ @@ -230,6 +230,29 @@ FT_BEGIN_HEADER #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 + + /*************************************************************************/ /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index 3581caaa6..58125c159 100644 --- 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, */ @@ -230,6 +230,29 @@ FT_BEGIN_HEADER #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 + + /*************************************************************************/ /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h index 871590ffd..297d6f017 100644 --- a/include/freetype/config/ftstdlib.h +++ b/include/freetype/config/ftstdlib.h @@ -82,16 +82,18 @@ #include -#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 diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h index 850eb5663..ce142c54c 100644 --- a/include/freetype/internal/ftdebug.h +++ b/include/freetype/internal/ftdebug.h @@ -141,7 +141,7 @@ FT_BEGIN_HEADER /* debug level in your appliaciton. */ /* */ FT_EXPORT( const char * ) - FT_Trace_Get_Name( FT_Int index ); + FT_Trace_Get_Name( FT_Int idx ); /*************************************************************************/ diff --git a/include/freetype/internal/ftrfork.h b/include/freetype/internal/ftrfork.h new file mode 100644 index 000000000..e7b10024a --- /dev/null +++ b/include/freetype/internal/ftrfork.h @@ -0,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 +#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 + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Raccess_Guess */ + /* */ + /* */ + /* 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]). */ + /* */ + /* */ + /* 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. */ + /* */ + /* */ + /* 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 ); + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Raccess_Get_HeaderInfo */ + /* */ + /* */ + /* 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. */ + /* */ + /* */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* rfork_offset :: */ + /* The file offset where the resource fork starts. */ + /* */ + /* */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* */ + /* 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 ); + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Raccess_Get_DataOffsets */ + /* */ + /* */ + /* 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. */ + /* */ + /* */ + /* 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. */ + /* */ + /* */ + /* 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. */ + /* */ + /* */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + /* */ + /* 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 */ diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h index 618f64aac..87576fd0e 100644 --- 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, */ @@ -315,6 +315,17 @@ FT_BEGIN_HEADER #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 ) FT_Stream_OpenMemory( FT_Stream stream, diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h index ffc0b1417..dffe9cfee 100644 --- 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( glyph ) /* glyph management (ftglyph.c) */ 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) */ diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h index 034878942..1e5ac44d5 100644 --- 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 #define FT_INTERNAL_SFNT_H #define FT_INTERNAL_SERVICE_H +#define FT_INTERNAL_RFORK_H #define FT_INTERNAL_TRUETYPE_TYPES_H #define FT_INTERNAL_TYPE1_TYPES_H diff --git a/src/base/Jamfile b/src/base/Jamfile index fbb7b39d0..d82e65d6d 100644 --- 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 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; if $(FT2_MULTI) { _sources = ftutil ftdbgmem ftstream ftcalc fttrigon ftgloadr ftoutln - ftobjs ftnames ; + ftobjs ftnames ftrfork ; } else { @@ -24,8 +24,7 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; # 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. # diff --git a/src/base/ftbase.c b/src/base/ftbase.c index 18a98c3a1..7d5a7fd8e 100644 --- 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" diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index bc3b15129..3f27cd70e 100644 --- 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,17 +1250,15 @@ 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 ) { 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; - } - 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 ) - { - 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_POST_Resource( library, stream, data_offsets, count, + face_index, aface ); + FT_FREE( data_offsets ); + return error; + } + + error = FT_Raccess_Get_DataOffsets( library, stream, + map_offset, rdara_pos, + FT_MAKE_TAG( 's', 'f', 'n', 't' ), + &data_offsets, &count ); + if ( !error ) + { + 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 ) + { + +#undef FT_COMPONENT +#define FT_COMPONENT trace_raccess + + FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); + error = IsMacResource( library, stream, 0, face_index, aface ); - /* Only meaningful on sytems with hfs+ drivers (or Macs) */ + FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); - 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_objs - - memory = library->memory; - - if ( FT_ALLOC( newpath, - ft_strlen( args->pathname ) + ft_strlen( "/rsrc" ) + 1 ) ) - goto Fail; - - ft_strcpy( newpath, args->pathname ); - ft_strcat( newpath, "/rsrc" ); - - 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 ); } - 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 ) ) ); diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c new file mode 100644 index 000000000..cf790ccc0 --- /dev/null +++ b/src/base/ftrfork.c @@ -0,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 +#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 */ diff --git a/src/base/rules.mk b/src/base/rules.mk index 725631b1d..8017e8589 100644 --- 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 @@ BASE_COMPILE := $(FT_COMPILE) $I$(subst /,$(COMPILER_SEP),$(SRC_DIR)/base) # # 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 @@ BASE_SRC := $(BASE_DIR)/ftcalc.c \ # 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 #