[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ft-devel] Hide Carbon-dependency of ftmac.c ([ft] cannot open some font
From: |
mpsuzuki |
Subject: |
[ft-devel] Hide Carbon-dependency of ftmac.c ([ft] cannot open some fonts on mac and linux) |
Date: |
Sat, 22 Sep 2007 18:32:54 +0900 |
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
address@hidden wrote:
>On Fri, 21 Sep 2007 00:32:35 +0200
>"David Turner" <address@hidden> 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;
+}
- [ft-devel] Hide Carbon-dependency of ftmac.c ([ft] cannot open some fonts on mac and linux),
mpsuzuki <=