From 27a4f9c4ac45ff65f941964f7351b64b1e6a9f35 Mon Sep 17 00:00:00 2001 From: scuri Date: Tue, 20 Oct 2009 17:20:18 +0000 Subject: *** empty log message *** --- src/freetype2/base/ftmac.c | 297 ++++++++++++++++++++------------------------- 1 file changed, 129 insertions(+), 168 deletions(-) (limited to 'src/freetype2/base/ftmac.c') diff --git a/src/freetype2/base/ftmac.c b/src/freetype2/base/ftmac.c index fd6201a..63f927d 100644 --- a/src/freetype2/base/ftmac.c +++ b/src/freetype2/base/ftmac.c @@ -8,7 +8,8 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, */ +/* 2009 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -67,7 +68,9 @@ #include #include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_STREAM_H +#include "ftbase.h" /* This is for Mac OS X. Without redefinition, OS_INLINE */ /* expands to `static inline' which doesn't survive the */ @@ -76,20 +79,36 @@ #undef OS_INLINE #define OS_INLINE static __inline__ #endif -#include -#ifndef HFS_MAXPATHLEN -#define HFS_MAXPATHLEN 1024 + /* `configure' checks the availability of `ResourceIndex' strictly */ + /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always. If it is */ + /* not set (e.g., a build without `configure'), the availability */ + /* is guessed from the SDK version. */ +#ifndef HAVE_TYPE_RESOURCE_INDEX +#if !defined( MAC_OS_X_VERSION_10_5 ) || \ + ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 ) +#define HAVE_TYPE_RESOURCE_INDEX 0 +#else +#define HAVE_TYPE_RESOURCE_INDEX 1 +#endif +#endif /* !HAVE_TYPE_RESOURCE_INDEX */ + +#if ( HAVE_TYPE_RESOURCE_INDEX == 0 ) + typedef short ResourceIndex; #endif +#include +#include +#include /* PATH_MAX */ + + /* Don't want warnings about our own use of deprecated functions. */ #define FT_DEPRECATED_ATTRIBUTE #include FT_MAC_H - /* undefine blocking-macros in ftmac.h */ -#undef FT_GetFile_From_Mac_Name( a, b, c ) -#undef FT_GetFile_From_Mac_ATS_Name( a, b, c ) -#undef FT_New_Face_From_FSSpec( a, b, c, d ) +#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */ +#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault +#endif /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over @@ -100,6 +119,7 @@ #endif + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, @@ -115,19 +135,28 @@ /* Private function. */ /* The FSSpec type has been discouraged for a long time, */ - /* but for some reason, there is no FSRef version of */ - /* ATSFontGetFileSpecification(), so we made our own. */ - /* Apple will provide one eventually. */ + /* unfortunately an FSRef replacement API for */ + /* ATSFontGetFileSpecification() is only available in */ + /* Mac OS X 10.5 and later. */ static OSStatus FT_ATSFontGetFileReference( ATSFontRef ats_font_id, FSRef* ats_font_ref ) { -#if __LP64__ +#if defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) + + OSStatus err; + + err = ATSFontGetFileReference( ats_font_id, ats_font_ref ); + + return err; +#elif __LP64__ /* No 64bit Carbon API on legacy platforms */ FT_UNUSED( ats_font_id ); FT_UNUSED( ats_font_ref ); + return fnfErr; -#else +#else /* 32bit Carbon API on legacy platforms */ OSStatus err; FSSpec spec; @@ -214,7 +243,8 @@ FSSpec* pathSpec, FT_Long* face_index ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) FT_UNUSED( fontName ); FT_UNUSED( pathSpec ); FT_UNUSED( face_index ); @@ -239,8 +269,8 @@ static OSErr - FT_FSPathMakeRes( const UInt8* pathname, - short* res ) + FT_FSPathMakeRes( const UInt8* pathname, + ResFileRefNum* res ) { OSErr err; FSRef ref; @@ -357,7 +387,7 @@ static void parse_fond( char* fond_data, short* have_sfnt, - short* sfnt_id, + ResID* sfnt_id, Str255 lwfn_file_name, short face_index ) { @@ -374,6 +404,10 @@ assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; + /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ + if ( 47 < face_index ) + return; + /* Let's do a little range checking before we get too excited here */ if ( face_index < count_faces_sfnt( fond_data ) ) { @@ -425,9 +459,10 @@ ft_memcpy(ps_name, names[0] + 1, ps_name_len); ps_name[ps_name_len] = 0; } - if ( style->indexes[0] > 1 ) + if ( style->indexes[face_index] > 1 && + style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) { - unsigned char* suffixes = names[style->indexes[0] - 1]; + unsigned char* suffixes = names[style->indexes[face_index] - 1]; for ( i = 1; i <= suffixes[0]; i++ ) @@ -463,8 +498,8 @@ UInt8* path_lwfn, size_t path_size ) { - FSRef ref, par_ref; - int dirname_len; + FSRef ref, par_ref; + size_t dirname_len; /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */ @@ -504,10 +539,10 @@ count_faces( Handle fond, const UInt8* pathname ) { - short sfnt_id; + ResID sfnt_id; short have_sfnt, have_lwfn; Str255 lwfn_file_name; - UInt8 buff[HFS_MAXPATHLEN]; + UInt8 buff[PATH_MAX]; FT_Error err; short num_faces; @@ -539,13 +574,13 @@ chunks are often not organized that way, so we glue chunks of the same type together. */ static FT_Error - read_lwfn( FT_Memory memory, - short res, - FT_Byte** pfb_data, - FT_ULong* size ) + read_lwfn( FT_Memory memory, + ResFileRefNum res, + FT_Byte** pfb_data, + FT_ULong* size ) { FT_Error error = FT_Err_Ok; - short res_id; + ResID res_id; unsigned char *buffer, *p, *size_p = NULL; FT_ULong total_size = 0; FT_ULong old_total_size = 0; @@ -563,7 +598,7 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( TTAG_POST, res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -602,7 +637,7 @@ for (;;) { - post_data = Get1Resource( 'POST', res_id++ ); + post_data = Get1Resource( TTAG_POST, res_id++ ); if ( post_data == NULL ) break; /* we are done */ @@ -654,120 +689,17 @@ } - /* Finalizer for a memory stream; gets called by FT_Done_Face(). - It frees the memory it uses. */ - static void - memory_stream_close( FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - FT_FREE( stream->base ); - - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Create a new memory stream from a buffer and a size. */ - static FT_Error - new_memory_stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream_CloseFunc close, - FT_Stream* astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !base ) - return FT_Err_Invalid_Argument; - - *astream = 0; - memory = library->memory; - if ( FT_NEW( stream ) ) - goto Exit; - - FT_Stream_OpenMemory( stream, base, size ); - - stream->close = close; - - *astream = stream; - - Exit: - return error; - } - - - /* Create a new FT_Face given a buffer and a driver name. */ - static FT_Error - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - char* driver_name, - FT_Face* aface ) - { - FT_Open_Args args; - FT_Error error; - FT_Stream stream; - FT_Memory memory = library->memory; - - - error = new_memory_stream( library, - base, - size, - memory_stream_close, - &stream ); - if ( error ) - { - FT_FREE( base ); - return error; - } - - args.flags = FT_OPEN_STREAM; - args.stream = stream; - if ( driver_name ) - { - args.flags = args.flags | FT_OPEN_DRIVER; - args.driver = FT_Get_Module( library, driver_name ); - } - - /* At this point, face_index has served its purpose; */ - /* whoever calls this function has already used it to */ - /* locate the correct font data. We should not propagate */ - /* this index to FT_Open_Face() (unless it is negative). */ - - if ( face_index > 0 ) - face_index = 0; - - error = FT_Open_Face( library, &args, face_index, aface ); - if ( error == FT_Err_Ok ) - (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - else - FT_Stream_Free( stream, 0 ); - - return error; - } - - - /* Create a new FT_Face from a file spec to an LWFN file. */ + /* Create a new FT_Face from a file path to an LWFN file. */ static FT_Error FT_New_Face_From_LWFN( FT_Library library, const UInt8* pathname, FT_Long face_index, FT_Face* aface ) { - FT_Byte* pfb_data; - FT_ULong pfb_size; - FT_Error error; - short res; + FT_Byte* pfb_data; + FT_ULong pfb_size; + FT_Error error; + ResFileRefNum res; if ( noErr != FT_FSPathMakeRes( pathname, &res ) ) @@ -792,7 +724,7 @@ /* Create a new FT_Face from an SFNT resource, specified by res ID. */ static FT_Error FT_New_Face_From_SFNT( FT_Library library, - short sfnt_id, + ResID sfnt_id, FT_Long face_index, FT_Face* aface ) { @@ -801,11 +733,11 @@ size_t sfnt_size; FT_Error error = FT_Err_Ok; FT_Memory memory = library->memory; - int is_cff; + int is_cff, is_sfnt_ps; - sfnt = GetResource( 'sfnt', sfnt_id ); - if ( ResError() ) + sfnt = GetResource( TTAG_sfnt, sfnt_id ); + if ( sfnt == NULL ) return FT_Err_Invalid_Handle; sfnt_size = (FT_ULong)GetHandleSize( sfnt ); @@ -818,31 +750,56 @@ ft_memcpy( sfnt_data, *sfnt, sfnt_size ); ReleaseResource( sfnt ); - is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; + is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 ); + is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 ); - return open_face_from_buffer( library, - sfnt_data, - sfnt_size, - face_index, - is_cff ? "cff" : "truetype", - aface ); + if ( is_sfnt_ps ) + { + FT_Stream stream; + + + if ( FT_NEW( stream ) ) + goto Try_OpenType; + + FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size ); + if ( !open_face_PS_from_sfnt_stream( library, + stream, + face_index, + 0, NULL, + aface ) ) + { + FT_Stream_Close( stream ); + FT_FREE( stream ); + FT_FREE( sfnt_data ); + goto Exit; + } + + FT_FREE( stream ); + } + Try_OpenType: + error = open_face_from_buffer( library, + sfnt_data, + sfnt_size, + face_index, + is_cff ? "cff" : "truetype", + aface ); + Exit: + return error; } - /* Create a new FT_Face from a file spec to a suitcase file. */ + /* Create a new FT_Face from a file path to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, const UInt8* pathname, FT_Long face_index, FT_Face* aface ) { - FT_Error error = FT_Err_Cannot_Open_Resource; - short res_ref, res_index; - Handle fond; - short num_faces_in_res, num_faces_in_fond; + FT_Error error = FT_Err_Cannot_Open_Resource; + ResFileRefNum res_ref; + ResourceIndex res_index; + Handle fond; + short num_faces_in_res, num_faces_in_fond; if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) ) @@ -855,7 +812,7 @@ num_faces_in_res = 0; for ( res_index = 1; ; ++res_index ) { - fond = Get1IndResource( 'FOND', res_index ); + fond = Get1IndResource( TTAG_FOND, res_index ); if ( ResError() ) break; @@ -869,7 +826,7 @@ } CloseResFile( res_ref ); - if ( FT_Err_Ok == error && NULL != aface ) + if ( FT_Err_Ok == error && NULL != aface && NULL != *aface ) (*aface)->num_faces = num_faces_in_res; return error; } @@ -883,25 +840,25 @@ FT_Long face_index, FT_Face* aface ) { - short sfnt_id, have_sfnt, have_lwfn = 0; - short fond_id; + short have_sfnt, have_lwfn = 0; + ResID sfnt_id, fond_id; OSType fond_type; Str255 fond_name; Str255 lwfn_file_name; - UInt8 path_lwfn[HFS_MAXPATHLEN]; + UInt8 path_lwfn[PATH_MAX]; OSErr err; FT_Error error = FT_Err_Ok; GetResInfo( fond, &fond_id, &fond_type, fond_name ); - if ( ResError() != noErr || fond_type != 'FOND' ) + if ( ResError() != noErr || fond_type != TTAG_FOND ) return FT_Err_Invalid_File_Format; parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); if ( lwfn_file_name[0] ) { - short res; + ResFileRefNum res; res = HomeResFile( fond ); @@ -909,7 +866,7 @@ goto found_no_lwfn_file; { - UInt8 path_fond[HFS_MAXPATHLEN]; + UInt8 path_fond[PATH_MAX]; FSRef ref; @@ -961,7 +918,7 @@ /* LWFN is a (very) specific file format, check for it explicitly */ file_type = get_file_type_from_path( pathname ); - if ( file_type == 'LWFN' ) + if ( file_type == TTAG_LWFN ) return FT_New_Face_From_LWFN( library, pathname, face_index, aface ); /* Otherwise the file type doesn't matter (there are more than */ @@ -1029,6 +986,8 @@ /* FT_New_Face_From_FSRef is identical to FT_New_Face except it */ /* accepts an FSRef instead of a path. */ /* */ + /* This function is deprecated because Carbon data types (FSRef) */ + /* are not cross-platform, and thus not suitable for the freetype API. */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, @@ -1038,7 +997,7 @@ FT_Error error; FT_Open_Args args; OSErr err; - UInt8 pathname[HFS_MAXPATHLEN]; + UInt8 pathname[PATH_MAX]; if ( !ref ) @@ -1068,13 +1027,15 @@ /* FT_New_Face_From_FSSpec is identical to FT_New_Face except it */ /* accepts an FSSpec instead of a path. */ /* */ + /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSSpec( FT_Library library, const FSSpec* spec, FT_Long face_index, FT_Face* aface ) { -#if __LP64__ +#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) ) FT_UNUSED( library ); FT_UNUSED( spec ); FT_UNUSED( face_index ); -- cgit v1.2.3