80#if !HAVE_ANSI_OS_INLINE
82#define OS_INLINE static __inline__
89#ifndef HAVE_TYPE_RESOURCE_INDEX
90#if !defined( MAC_OS_X_VERSION_10_5 ) || \
91 ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 )
92#define HAVE_TYPE_RESOURCE_INDEX 0
94#define HAVE_TYPE_RESOURCE_INDEX 1
98#if ( HAVE_TYPE_RESOURCE_INDEX == 0 )
99 typedef short ResourceIndex;
102#include <CoreServices/CoreServices.h>
103#include <ApplicationServices/ApplicationServices.h>
104#include <sys/syslimits.h>
107#define FT_DEPRECATED_ATTRIBUTE
111#ifndef kATSOptionFlagsUnRestrictedScope
112#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault
125 FT_EXPORT_DEF( FT_Error )
126 FT_GetFile_From_Mac_Name(
const char* fontName,
128 FT_Long* face_index )
130 FT_UNUSED( fontName );
131 FT_UNUSED( pathSpec );
132 FT_UNUSED( face_index );
134 return FT_THROW( Unimplemented_Feature );
144 FT_ATSFontGetFileReference( ATSFontRef ats_font_id,
145 FSRef* ats_font_ref )
147#if defined( MAC_OS_X_VERSION_10_5 ) && \
148 ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
152 err = ATSFontGetFileReference( ats_font_id, ats_font_ref );
156 FT_UNUSED( ats_font_id );
157 FT_UNUSED( ats_font_ref );
166 err = ATSFontGetFileSpecification( ats_font_id, &spec );
168 err = FSpMakeFSRef( &spec, ats_font_ref );
176 FT_GetFileRef_From_Mac_ATS_Name(
const char* fontName,
178 FT_Long* face_index )
180 CFStringRef cf_fontName;
181 ATSFontRef ats_font_id;
186 cf_fontName = CFStringCreateWithCString( NULL, fontName,
187 kCFStringEncodingMacRoman );
188 ats_font_id = ATSFontFindFromName( cf_fontName,
189 kATSOptionFlagsUnRestrictedScope );
190 CFRelease( cf_fontName );
192 if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )
193 return FT_THROW( Unknown_File_Format );
195 if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) )
196 return FT_THROW( Unknown_File_Format );
201 ATSFontRef id2 = ats_font_id - 1;
207 if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) )
209 if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) )
214 *face_index = ats_font_id - ( id2 + 1 );
221 FT_EXPORT_DEF( FT_Error )
222 FT_GetFilePath_From_Mac_ATS_Name(
const char* fontName,
225 FT_Long* face_index )
231 if ( !fontName || !face_index )
232 return FT_THROW( Invalid_Argument);
234 err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
238 if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) )
239 return FT_THROW( Unknown_File_Format );
246 FT_EXPORT_DEF( FT_Error )
247 FT_GetFile_From_Mac_ATS_Name(
const char* fontName,
249 FT_Long* face_index )
251#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
252 ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
253 FT_UNUSED( fontName );
254 FT_UNUSED( pathSpec );
255 FT_UNUSED( face_index );
257 return FT_THROW( Unimplemented_Feature );
263 if ( !fontName || !face_index )
264 return FT_THROW( Invalid_Argument );
266 err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
270 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL,
272 return FT_THROW( Unknown_File_Format );
280 FT_FSPathMakeRes(
const UInt8* pathname,
287 if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
288 return FT_THROW( Cannot_Open_Resource );
291 err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
296 *res = FSOpenResFile( &ref, fsRdPerm );
305 get_file_type_from_path(
const UInt8* pathname )
311 if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
314 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info,
318 return ( (FInfo *)( info.finderInfo ) )->fdType;
324 create_lwfn_name(
char* ps_name,
325 Str255 lwfn_file_name )
327 int max = 5, count = 0;
328 FT_Byte* p = lwfn_file_name;
329 FT_Byte* q = (FT_Byte*)ps_name;
332 lwfn_file_name[0] = 0;
336 if ( ft_isupper( *q ) )
342 if ( count < max && ( ft_isalnum( *q ) || *q ==
'_' ) )
354 count_faces_sfnt(
char* fond_data )
359 return EndianS16_BtoN( *( (
short*)( fond_data +
360 sizeof ( FamRec ) ) ) ) + 1;
365 count_faces_scalable(
char* fond_data )
368 short i, face, face_all;
371 face_all = EndianS16_BtoN( *( (
short *)( fond_data +
372 sizeof ( FamRec ) ) ) ) + 1;
373 assoc = (AsscEntry*)( fond_data +
sizeof ( FamRec ) + 2 );
376 for ( i = 0; i < face_all; i++ )
378 if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
394 parse_fond(
char* fond_data,
397 Str255 lwfn_file_name,
401 AsscEntry* base_assoc;
407 lwfn_file_name[0] = 0;
409 fond = (FamRec*)fond_data;
410 assoc = (AsscEntry*)( fond_data +
sizeof ( FamRec ) + 2 );
414 if ( 47 < face_index )
418 if ( face_index < count_faces_sfnt( fond_data ) )
424 if ( EndianS16_BtoN( assoc->fontSize ) == 0 )
427 *sfnt_id = EndianS16_BtoN( assoc->fontID );
429 else if ( base_assoc->fontSize == 0 )
432 *sfnt_id = EndianS16_BtoN( base_assoc->fontID );
436 if ( EndianS32_BtoN( fond->ffStylOff ) )
438 unsigned char* p = (
unsigned char*)fond_data;
440 unsigned short string_count;
442 unsigned char* names[64];
446 p += EndianS32_BtoN( fond->ffStylOff );
447 style = (StyleTable*)p;
448 p +=
sizeof ( StyleTable );
449 string_count = EndianS16_BtoN( *(
short*)(p) );
450 string_count = FT_MIN( 64, string_count );
451 p +=
sizeof ( short );
453 for ( i = 0; i < string_count; i++ )
461 size_t ps_name_len = (size_t)names[0][0];
464 if ( ps_name_len != 0 )
466 ft_memcpy( ps_name, names[0] + 1, ps_name_len );
467 ps_name[ps_name_len] = 0;
469 if ( style->indexes[face_index] > 1 &&
470 style->indexes[face_index] <= string_count )
472 unsigned char* suffixes = names[style->indexes[face_index] - 1];
475 for ( i = 1; i <= suffixes[0]; i++ )
478 size_t j = suffixes[i] - 1;
481 if ( j < string_count && ( s = names[j] ) != NULL )
483 size_t s_len = (size_t)s[0];
486 if ( s_len != 0 && ps_name_len + s_len <
sizeof ( ps_name ) )
488 ft_memcpy( ps_name + ps_name_len, s + 1, s_len );
489 ps_name_len += s_len;
490 ps_name[ps_name_len] = 0;
497 create_lwfn_name( ps_name, lwfn_file_name );
503 lookup_lwfn_by_fond(
const UInt8* path_fond,
504 ConstStr255Param base_lwfn,
515 if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) )
516 return FT_THROW( Invalid_Argument );
518 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,
519 NULL, NULL, NULL, &par_ref ) )
520 return FT_THROW( Invalid_Argument );
522 if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) )
523 return FT_THROW( Invalid_Argument );
525 if ( ft_strlen( (
char *)path_lwfn ) + 1 + base_lwfn[0] > path_size )
526 return FT_THROW( Invalid_Argument );
529 ft_strcat( (
char *)path_lwfn,
"/" );
530 dirname_len = ft_strlen( (
char *)path_lwfn );
531 ft_strcat( (
char *)path_lwfn, (
char *)base_lwfn + 1 );
532 path_lwfn[dirname_len + base_lwfn[0]] =
'\0';
534 if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) )
535 return FT_THROW( Cannot_Open_Resource );
537 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,
538 NULL, NULL, NULL, NULL ) )
539 return FT_THROW( Cannot_Open_Resource );
546 count_faces( Handle fond,
547 const UInt8* pathname )
550 short have_sfnt, have_lwfn;
551 Str255 lwfn_file_name;
552 UInt8 buff[PATH_MAX];
557 have_sfnt = have_lwfn = 0;
559 parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
561 if ( lwfn_file_name[0] )
563 err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
564 buff,
sizeof ( buff ) );
569 if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
572 num_faces = count_faces_scalable( *fond );
584 read_lwfn( FT_Memory memory,
589 FT_Error error = FT_Err_Ok;
591 unsigned char *buffer, *p, *size_p = NULL;
592 FT_ULong total_size = 0;
593 FT_ULong old_total_size = 0;
594 FT_ULong post_size, pfb_chunk_size;
596 char code, last_code;
608 post_data = Get1Resource( TTAG_POST, res_id++ );
612 code = (*post_data)[0];
614 if (
code != last_code )
622 total_size += (FT_ULong)GetHandleSize( post_data ) - 2;
626 if ( FT_MAC_RFORK_MAX_LEN < total_size )
628 error = FT_THROW( Array_Too_Large );
632 old_total_size = total_size;
635 if ( FT_QALLOC( buffer, (FT_Long)total_size ) )
647 post_data = Get1Resource( TTAG_POST, res_id++ );
651 post_size = (FT_ULong)GetHandleSize( post_data ) - 2;
652 code = (*post_data)[0];
654 if (
code != last_code )
656 if ( last_code != -1 )
661 *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF );
662 *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF );
663 *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF );
664 *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF );
672 else if (
code == 2 )
684 ft_memcpy( p, *post_data + 2, post_size );
685 pfb_chunk_size += post_size;
701 FT_New_Face_From_LWFN( FT_Library library,
702 const UInt8* pathname,
712 if ( noErr != FT_FSPathMakeRes( pathname, &res ) )
713 return FT_THROW( Cannot_Open_Resource );
717 error = read_lwfn( library->memory, res, &pfb_data, &pfb_size );
722 return open_face_from_buffer( library,
733 FT_New_Face_From_SFNT( FT_Library library,
741 FT_Error error = FT_Err_Ok;
742 FT_Memory memory = library->memory;
743 int is_cff, is_sfnt_ps;
746 sfnt = GetResource( TTAG_sfnt, sfnt_id );
748 return FT_THROW( Invalid_Handle );
750 sfnt_size = (FT_ULong)GetHandleSize( sfnt );
753 if ( FT_MAC_RFORK_MAX_LEN < sfnt_size )
754 return FT_THROW( Array_Too_Large );
756 if ( FT_QALLOC( sfnt_data, (FT_Long)sfnt_size ) )
758 ReleaseResource( sfnt );
762 ft_memcpy( sfnt_data, *sfnt, sfnt_size );
763 ReleaseResource( sfnt );
765 is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data,
"OTTO", 4 );
766 is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data,
"typ1", 4 );
773 if ( FT_NEW( stream ) )
776 FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );
777 if ( !open_face_PS_from_sfnt_stream( library,
783 FT_Stream_Close( stream );
785 FT_FREE( sfnt_data );
792 error = open_face_from_buffer( library,
796 is_cff ?
"cff" :
"truetype",
805 FT_New_Face_From_Suitcase( FT_Library library,
806 const UInt8* pathname,
810 FT_Error error = FT_ERR( Cannot_Open_Resource );
811 ResFileRefNum res_ref;
812 ResourceIndex res_index;
814 short num_faces_in_res;
818 if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) )
819 return FT_THROW( Cannot_Open_Resource );
821 UseResFile( res_ref );
823 return FT_THROW( Cannot_Open_Resource );
826 num_faces_in_res = 0;
830 short num_faces_in_fond;
833 fond = Get1IndResource( TTAG_FOND, res_index );
837 num_faces_in_fond = count_faces( fond, pathname );
838 num_faces_in_res += num_faces_in_fond;
840 if ( count < num_faces_in_fond )
841 error = FT_New_Face_From_FOND( library, fond, count, aface );
844 count -= num_faces_in_fond;
847 CloseResFile( res_ref );
849 if ( !error && aface && *aface )
851 (*aface)->num_faces = num_faces_in_res;
852 (*aface)->face_index = face_index;
861 FT_EXPORT_DEF( FT_Error )
862 FT_New_Face_From_FOND( FT_Library library,
867 short have_sfnt, have_lwfn = 0;
868 ResID sfnt_id, fond_id;
871 Str255 lwfn_file_name;
872 UInt8 path_lwfn[PATH_MAX];
874 FT_Error error = FT_Err_Ok;
879 GetResInfo( fond, &fond_id, &fond_type, fond_name );
880 if ( ResError() != noErr || fond_type != TTAG_FOND )
881 return FT_THROW( Invalid_File_Format );
883 parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
885 if ( lwfn_file_name[0] )
890 res = HomeResFile( fond );
891 if ( noErr != ResError() )
892 goto found_no_lwfn_file;
895 UInt8 path_fond[PATH_MAX];
899 err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum,
900 NULL, NULL, NULL, &ref, NULL );
902 goto found_no_lwfn_file;
904 err = FSRefMakePath( &ref, path_fond,
sizeof ( path_fond ) );
906 goto found_no_lwfn_file;
908 error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
909 path_lwfn,
sizeof ( path_lwfn ) );
915 if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
916 error = FT_New_Face_From_LWFN( library,
921 error = FT_THROW( Unknown_File_Format );
924 if ( have_sfnt && error )
925 error = FT_New_Face_From_SFNT( library,
936 FT_New_Face_From_Resource( FT_Library library,
937 const UInt8* pathname,
946 file_type = get_file_type_from_path( pathname );
947 if ( file_type == TTAG_LWFN )
948 return FT_New_Face_From_LWFN( library, pathname, face_index, aface );
954 error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface );
977 FT_EXPORT_DEF( FT_Error )
978 FT_New_Face( FT_Library library,
979 const char* pathname,
989 return FT_THROW( Invalid_Argument );
994 error = FT_New_Face_From_Resource( library, (UInt8 *)pathname,
996 if ( error || *aface )
1000 args.flags = FT_OPEN_PATHNAME;
1001 args.pathname = (
char*)pathname;
1003 return FT_Open_Face( library, &args, face_index, aface );
1019 FT_EXPORT_DEF( FT_Error )
1020 FT_New_Face_From_FSRef( FT_Library library,
1029 UInt8 pathname[PATH_MAX];
1036 return FT_THROW( Invalid_Argument );
1038 err = FSRefMakePath( ref, pathname,
sizeof ( pathname ) );
1040 error = FT_THROW( Cannot_Open_Resource );
1042 error = FT_New_Face_From_Resource( library, pathname, face_index, aface );
1043 if ( error || *aface )
1047 args.flags = FT_OPEN_PATHNAME;
1048 args.pathname = (
char*)pathname;
1049 return FT_Open_Face( library, &args, face_index, aface );
1064 FT_EXPORT_DEF( FT_Error )
1065 FT_New_Face_From_FSSpec( FT_Library library,
1070#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
1071 ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
1072 FT_UNUSED( library );
1074 FT_UNUSED( face_index );
1077 return FT_THROW( Unimplemented_Feature );
1084 if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr )
1085 return FT_THROW( Invalid_Argument );
1087 return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
1094 typedef int ft_mac_dummy_;