Hi, Recently David Turner proposed to use dlsym()-type features for ftmac.c to solve the incompatibilities of libfreetype.dylib with ftmac.c and without ftmac.c, in freetype mailing list.
As a proof of his idea, I wrote a sample header file "ftmacdyn.h" to replace Carbon-derived functions in ftmac.c by the function pointers. By including ftmacdyn.h, ftmac.c is changed to resolve the Carbon functions in runtime, without writing the code but insersion a few initialization routines. libfreetype.dylib has no explicit symbol reference to Carbon frameworks. I want to discuss with developers importing Unix applications to Mac OS X, about the idea using such hook to remove the explicit symbol reference of Mac OS specific frameworks. -- I think it's sufficient as a draft for further discussion, but attached ftmacdyn.h is NOT finished work, there are several issues: * CPP feature: Current ftmacdyn.h uses C99 preprocessor macros (to handle variadic arguments). They are incompatible with "-ansi" option. The legacy C compiler of Mac OS X 10.0 (using precompiled header by default) cannot process it by default. * Softening of compiler's inspection: The types of function pointers are declared by ftmacdyn.h, not by the system. The mismatching between ftmacdyn.h and system cannot be checked. Either the deprecated functions cannot be found. * Maintainancability: If a developer inserts ftmac.c new Carbon functions, he has to update ftmacdyn.h: declaration of function pointer types, allocation of function pointer, and initialization of function pointer. It's troublesome. If he slipped to update ftmacdyn.h, he will receive unexpected error in both phases of compilation of libfreetype.dylib and linking built libfreetype with other applications. I think these issues must be solved by auto generation of ftmacdyn.h. It's not difficult to generate ftmacdyn.h if we have the list of required Carbon functions. The compilation of ftmac.c (without ftmacdyn.h) is convenient to obtain the list and check type mismatching issues, but repeating compile ftmac.c, generate ftmacdyn.h, recompile ftmac.c is not smart, even if it's automatic. Regards, mpsuzuki On Fri, 21 Sep 2007 17:31:35 +0900 [EMAIL PROTECTED] wrote: >On Fri, 21 Sep 2007 00:32:35 +0200 >"David Turner" <[EMAIL PROTECTED]> wrote: >>the traditional, and painful, way to deal with this sort of problems >>in a seamless way (at least for the user) is to use dlopen()-style dynamic >>linking to access the "missing" Carbon functions. > >>do you think it'd be possible to add this to FreeType, to get rid of the >>--with-old-mac-fonts and related issues ? > >I think it's possible. > >>I know it's non trivial work, but that would be the right thing to do. > >Although I've proposed a replacement by Carbon-free MacOS >font support, I have to agree this pointing out. ftmac.c >provides a few functions that cannot be implemented without >QuickDraw or ATS (getting a font file from QuickDraw/ATS >font name), runtime resolving of Carbon dependency is required >to provide these functions safely. > >The expected procedure would be: > >step 1: check whether runtime linker has already loaded > Carbon framework (even if the application developer > doesn't care Carbon-dependent feature of FreeType, > some applications load Carbon framework for other > purpose, e.g. to use native GUI library etc). > >step 2: if Carbon framework is not loaded, try to load it. > if could not load, returniappropriate error. > >step 3: if Carbon framework is loaded, try to resolve > required Carbon-dependent symbols. If could not > resolve, return appropriate error. > >In last year, I've written testing code for step 3 during >the discussion about how to deprecate the legacy Carbon >functions. > >The headache is, step 1 + 2 are expected to be implemented >without non-standard frameworks, to avoid unexpected dependency. >If the softwares are built only with POSIX APIs, the binaries >are linked with libSystem.B.dylib only. The external libraries >(e.g. libdl.dylib or CoreFoundation framework) should not be >used even if they provide convenient functions. > >The latest libSystem.B.dylib on Mac OS X 10.4 includes dlsym(), >but older libSystem.B.dylib on Mac OS X 10.{0, 1} doesn't. >In such old systems, NSIsSymbolNameDefined() may be used for, >but they are deprecated :-( I have to think over smart >implementation after the investigation of function availabilities >on each Mac OS X revisions. Anyway, I will write small code >to demonstrate on specific platform within 1 month, please wait. > >Regards, >mpsuzuki Index: src/base/ftmac.c =================================================================== RCS file: /sources/freetype/freetype2/src/base/ftmac.c,v retrieving revision 1.59 diff -u -r1.59 ftmac.c --- src/base/ftmac.c 29 Aug 2007 06:08:59 -0000 1.59 +++ src/base/ftmac.c 22 Sep 2007 08:30:21 -0000 @@ -91,6 +95,8 @@ #undef FT_GetFile_From_Mac_ATS_Name( a, b, c ) #undef FT_New_Face_From_FSSpec( a, b, c, d ) +#define FT_InitCarbonFuncPtrs() do ; while ( 0 ) +#include <ftmacdyn.h> /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over TrueType in case *both* are available (this is not common, @@ -133,6 +139,8 @@ FSSpec spec; + FT_InitCarbonFuncPtrs(); + err = ATSFontGetFileSpecification( ats_font_id, &spec ); if ( noErr == err ) err = FSpMakeFSRef( &spec, ats_font_ref ); @@ -198,6 +206,8 @@ FT_Error err; + FT_InitCarbonFuncPtrs(); + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( FT_Err_Ok != err ) return err; @@ -226,6 +236,8 @@ FT_Error err; + FT_InitCarbonFuncPtrs(); + err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( FT_Err_Ok != err ) return err; @@ -895,6 +907,8 @@ FT_Error error = FT_Err_Ok; + FT_InitCarbonFuncPtrs(); + GetResInfo( fond, &fond_id, &fond_type, fond_name ); if ( ResError() != noErr || fond_type != 'FOND' ) return FT_Err_Invalid_File_Format; @@ -1009,6 +1023,8 @@ error = FT_Err_Ok; *aface = NULL; + FT_InitCarbonFuncPtrs(); + /* try resourcefork based font: LWFN, FFIL */ error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, face_index, aface ); @@ -1046,6 +1062,7 @@ if ( !ref ) return FT_Err_Invalid_Argument; + FT_InitCarbonFuncPtrs(); err = FSRefMakePath( ref, pathname, sizeof ( pathname ) ); if ( err ) error = FT_Err_Cannot_Open_Resource; @@ -1088,6 +1105,7 @@ FSRef ref; + FT_InitCarbonFuncPtrs(); if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr ) return FT_Err_Invalid_Argument; else --- /dev/null 2007-09-18 12:46:17.498542285 +0900 +++ src/base/ftmacdyn.h 2007-09-22 05:44:36.000000000 +0900 @@ -0,0 +1,140 @@ +#include <mach-o/dyld.h> +#undef FT_InitCarbonFuncPtrs() + +/* symbols in CoreFoundation framework */ +#define CFRelease(...) (*dyn_CFRelease)(__VA_ARGS__) +#define CFStringCreateWithCString(...) (*dyn_CFStringCreateWithCString)(__VA_ARGS__) + +/* symbols in FileManager framework */ +#define FSCompareFSRefs(...) (*dyn_FSCompareFSRefs)(__VA_ARGS__) +#define FSGetCatalogInfo(...) (*dyn_FSGetCatalogInfo)(__VA_ARGS__) +#define FSGetForkCBInfo(...) (*dyn_FSGetForkCBInfo)(__VA_ARGS__) +#define FSOpenResFile(...) (*dyn_FSOpenResFile)(__VA_ARGS__) +#define FSOpenResourceFile(...) (*dyn_FSOpenResourceFile)(__VA_ARGS__) +#define FSPathMakeRef(...) (*dyn_FSPathMakeRef)(__VA_ARGS__) +#define FSRefMakePath(...) (*dyn_FSRefMakePath)(__VA_ARGS__) +#define FSpMakeFSRef(...) (*dyn_FSpMakeFSRef)(__VA_ARGS__) +#define CloseResFile(...) (*dyn_CloseResFile)(__VA_ARGS__) +#define Get1IndResource(...) (*dyn_Get1IndResource)(__VA_ARGS__) +#define Get1Resource(...) (*dyn_Get1Resource)(__VA_ARGS__) +#define GetHandleSize(...) (*dyn_GetHandleSize)(__VA_ARGS__) +#define GetResInfo(...) (*dyn_GetResInfo)(__VA_ARGS__) +#define GetResource(...) (*dyn_GetResource)(__VA_ARGS__) +#define HomeResFile(...) (*dyn_HomeResFile)(__VA_ARGS__) +#define ReleaseResource(...) (*dyn_ReleaseResource)(__VA_ARGS__) +#define ResError(...) (*dyn_ResError)(__VA_ARGS__) +#define UseResFile(...) (*dyn_UseResFile)(__VA_ARGS__) + + +/* symbols in ATS framework */ +#define ATSFontFindFromName(...) (*dyn_ATSFontFindFromName)(__VA_ARGS__) +#define ATSFontGetFileSpecification(...) (*dyn_ATSFontGetFileSpecification)(__VA_ARGS__) + +#define ALLOC_CARBON_FUNC_PTR( func_name ) \ + dyn##func_name##_t dyn##func_name + +#define INIT_CARBON_FUNC_PTR( func_name ) \ + *(void **)(&(dyn##func_name)) = ( NSIsSymbolNameDefined( #func_name ) && NSLookupAndBindSymbol( #func_name ) ? \ + NSAddressOfSymbol( NSLookupAndBindSymbol( #func_name ) ) : NULL ) + +#define DEFAULT_CORESERVICES_OBJ "/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices" +#define DEFAULT_APPLICATIONSERVICES_OBJ "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices" + +typedef void ( *dyn_CFRelease_t )( CFTypeRef ); +typedef CFStringRef ( *dyn_CFStringCreateWithCString_t )( CFAllocatorRef, const char*, CFStringEncoding ); +typedef Size ( *dyn_GetHandleSize_t )( Handle ) ; +typedef OSErr ( *dyn_FSpMakeFSRef_t )( const FSSpec*, FSRef* ) ; +typedef OSErr ( *dyn_FSCompareFSRefs_t )( const FSRef*, const FSRef* ) ; +typedef OSErr ( *dyn_FSGetCatalogInfo_t )( const FSRef*, FSCatalogInfoBitmap, FSCatalogInfo*, HFSUniStr255*, FSSpec*, FSRef* ) ; +typedef OSErr ( *dyn_FSGetForkCBInfo_t )( SInt16, FSVolumeRefNum, SInt16*, SInt16*, FSForkInfo*, FSRef*, HFSUniStr255* ) ; +typedef OSStatus ( *dyn_FSRefMakePath_t )( const FSRef*, UInt8*, UInt32 ) ; +typedef OSStatus ( *dyn_FSPathMakeRef_t )( const UInt8*, FSRef*, Boolean* ) ; +typedef void ( *dyn_CloseResFile_t )( short ) ; +typedef OSErr ( *dyn_ResError_t )( void ) ; +typedef short ( *dyn_HomeResFile_t )( Handle ) ; +typedef void ( *dyn_UseResFile_t )( short ) ; +typedef Handle ( *dyn_Get1IndResource_t )( ResType, short ) ; +typedef Handle ( *dyn_GetResource_t )( ResType, short ) ; +typedef Handle ( *dyn_Get1Resource_t )( ResType, short ) ; +typedef void ( *dyn_ReleaseResource_t )( Handle ) ; +typedef void ( *dyn_GetResInfo_t )( Handle, short*, ResType*, Str255 ) ; +typedef short ( *dyn_FSOpenResFile_t )( const FSRef*, SInt8 ) ; +typedef OSErr ( *dyn_FSOpenResourceFile_t )( const FSRef*, UniCharCount, const UniChar*, SInt8, SInt16* ) ; +typedef ATSFontRef ( *dyn_ATSFontFindFromName_t )( CFStringRef, ATSOptionFlags ) ; +typedef OSStatus ( *dyn_ATSFontGetFileSpecification_t )( ATSFontRef, FSSpec* ) ; + +ALLOC_CARBON_FUNC_PTR( _CFRelease ); +ALLOC_CARBON_FUNC_PTR( _CFStringCreateWithCString ); + +ALLOC_CARBON_FUNC_PTR( _CloseResFile ); +ALLOC_CARBON_FUNC_PTR( _Get1IndResource ); +ALLOC_CARBON_FUNC_PTR( _Get1Resource ); +ALLOC_CARBON_FUNC_PTR( _GetHandleSize ); +ALLOC_CARBON_FUNC_PTR( _GetResInfo ); +ALLOC_CARBON_FUNC_PTR( _GetResource ); +ALLOC_CARBON_FUNC_PTR( _HomeResFile ); +ALLOC_CARBON_FUNC_PTR( _ReleaseResource ); +ALLOC_CARBON_FUNC_PTR( _ResError ); +ALLOC_CARBON_FUNC_PTR( _UseResFile ); + +ALLOC_CARBON_FUNC_PTR( _FSCompareFSRefs ); +ALLOC_CARBON_FUNC_PTR( _FSGetCatalogInfo ); +ALLOC_CARBON_FUNC_PTR( _FSGetForkCBInfo ); +ALLOC_CARBON_FUNC_PTR( _FSOpenResFile ); +ALLOC_CARBON_FUNC_PTR( _FSOpenResourceFile ); +ALLOC_CARBON_FUNC_PTR( _FSPathMakeRef ); +ALLOC_CARBON_FUNC_PTR( _FSRefMakePath ); +ALLOC_CARBON_FUNC_PTR( _FSpMakeFSRef ); + +ALLOC_CARBON_FUNC_PTR( _ATSFontFindFromName ) ; +ALLOC_CARBON_FUNC_PTR( _ATSFontGetFileSpecification ) ; + +FT_Bool ft_carbon_func_ptr_initialized = 0; + +int +FT_InitCarbonFuncPtrs() +{ + if ( ft_carbon_func_ptr_initialized ) + return 0; + + if ( !NSIsSymbolNameDefined( "_CoreServicesVersionNumber" ) ) + { + if ( !NSAddLibraryWithSearching( DEFAULT_CORESERVICES_OBJ ) ) + return -1; + } + + INIT_CARBON_FUNC_PTR( _CFRelease ); + INIT_CARBON_FUNC_PTR( _CFStringCreateWithCString ); + + INIT_CARBON_FUNC_PTR( _CloseResFile ); + INIT_CARBON_FUNC_PTR( _Get1IndResource ); + INIT_CARBON_FUNC_PTR( _Get1Resource ); + INIT_CARBON_FUNC_PTR( _GetHandleSize ); + INIT_CARBON_FUNC_PTR( _GetResInfo ); + INIT_CARBON_FUNC_PTR( _GetResource ); + INIT_CARBON_FUNC_PTR( _HomeResFile ); + INIT_CARBON_FUNC_PTR( _ReleaseResource ); + INIT_CARBON_FUNC_PTR( _ResError ); + INIT_CARBON_FUNC_PTR( _UseResFile ); + + INIT_CARBON_FUNC_PTR( _FSCompareFSRefs ); + INIT_CARBON_FUNC_PTR( _FSGetCatalogInfo ); + INIT_CARBON_FUNC_PTR( _FSGetForkCBInfo ); + INIT_CARBON_FUNC_PTR( _FSOpenResFile ); + INIT_CARBON_FUNC_PTR( _FSOpenResourceFile ); + INIT_CARBON_FUNC_PTR( _FSPathMakeRef ); + INIT_CARBON_FUNC_PTR( _FSRefMakePath ); + INIT_CARBON_FUNC_PTR( _FSpMakeFSRef ); + + if ( !NSIsSymbolNameDefined( "_ApplicationServicesVersionNumber" ) ) + { + if ( !NSAddLibraryWithSearching( DEFAULT_APPLICATIONSERVICES_OBJ ) ) + return -2; + } + + INIT_CARBON_FUNC_PTR( _ATSFontFindFromName ) ; + INIT_CARBON_FUNC_PTR( _ATSFontGetFileSpecification ) ; + + ft_carbon_func_ptr_initialized = 1; + return 0; +} _______________________________________________ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel