00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #include <ft2build.h>
00070 #include FT_FREETYPE_H
00071 #include FT_TRUETYPE_TAGS_H
00072 #include FT_INTERNAL_STREAM_H
00073 #include "ftbase.h"
00074
00075
00076
00077
00078 #if !HAVE_ANSI_OS_INLINE
00079 #undef OS_INLINE
00080 #define OS_INLINE static __inline__
00081 #endif
00082
00083
00084
00085
00086
00087 #ifndef HAVE_TYPE_RESOURCE_INDEX
00088 #if !defined( MAC_OS_X_VERSION_10_5 ) || \
00089 ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 )
00090 #define HAVE_TYPE_RESOURCE_INDEX 0
00091 #else
00092 #define HAVE_TYPE_RESOURCE_INDEX 1
00093 #endif
00094 #endif
00095
00096 #if ( HAVE_TYPE_RESOURCE_INDEX == 0 )
00097 typedef short ResourceIndex;
00098 #endif
00099
00100 #include <CoreServices/CoreServices.h>
00101 #include <ApplicationServices/ApplicationServices.h>
00102 #include <sys/syslimits.h>
00103
00104
00105 #define FT_DEPRECATED_ATTRIBUTE
00106
00107 #include FT_MAC_H
00108
00109 #ifndef kATSOptionFlagsUnRestrictedScope
00110 #define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault
00111 #endif
00112
00113
00114
00115
00116
00117 #ifndef PREFER_LWFN
00118 #define PREFER_LWFN 1
00119 #endif
00120
00121
00122
00123 FT_EXPORT_DEF( FT_Error )
00124 FT_GetFile_From_Mac_Name( const char* fontName,
00125 FSSpec* pathSpec,
00126 FT_Long* face_index )
00127 {
00128 FT_UNUSED( fontName );
00129 FT_UNUSED( pathSpec );
00130 FT_UNUSED( face_index );
00131
00132 return FT_Err_Unimplemented_Feature;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 static OSStatus
00142 FT_ATSFontGetFileReference( ATSFontRef ats_font_id,
00143 FSRef* ats_font_ref )
00144 {
00145 #if defined( MAC_OS_X_VERSION_10_5 ) && \
00146 ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
00147
00148 OSStatus err;
00149
00150 err = ATSFontGetFileReference( ats_font_id, ats_font_ref );
00151
00152 return err;
00153 #elif __LP64__
00154 FT_UNUSED( ats_font_id );
00155 FT_UNUSED( ats_font_ref );
00156
00157
00158 return fnfErr;
00159 #else
00160 OSStatus err;
00161 FSSpec spec;
00162
00163
00164 err = ATSFontGetFileSpecification( ats_font_id, &spec );
00165 if ( noErr == err )
00166 err = FSpMakeFSRef( &spec, ats_font_ref );
00167
00168 return err;
00169 #endif
00170 }
00171
00172
00173 static FT_Error
00174 FT_GetFileRef_From_Mac_ATS_Name( const char* fontName,
00175 FSRef* ats_font_ref,
00176 FT_Long* face_index )
00177 {
00178 CFStringRef cf_fontName;
00179 ATSFontRef ats_font_id;
00180
00181
00182 *face_index = 0;
00183
00184 cf_fontName = CFStringCreateWithCString( NULL, fontName,
00185 kCFStringEncodingMacRoman );
00186 ats_font_id = ATSFontFindFromName( cf_fontName,
00187 kATSOptionFlagsUnRestrictedScope );
00188 CFRelease( cf_fontName );
00189
00190 if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )
00191 return FT_Err_Unknown_File_Format;
00192
00193 if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) )
00194 return FT_Err_Unknown_File_Format;
00195
00196
00197
00198 {
00199 ATSFontRef id2 = ats_font_id - 1;
00200 FSRef ref2;
00201
00202
00203 while ( id2 > 0 )
00204 {
00205 if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) )
00206 break;
00207 if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) )
00208 break;
00209
00210 id2 --;
00211 }
00212 *face_index = ats_font_id - ( id2 + 1 );
00213 }
00214
00215 return FT_Err_Ok;
00216 }
00217
00218
00219 FT_EXPORT_DEF( FT_Error )
00220 FT_GetFilePath_From_Mac_ATS_Name( const char* fontName,
00221 UInt8* path,
00222 UInt32 maxPathSize,
00223 FT_Long* face_index )
00224 {
00225 FSRef ref;
00226 FT_Error err;
00227
00228
00229 err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
00230 if ( FT_Err_Ok != err )
00231 return err;
00232
00233 if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) )
00234 return FT_Err_Unknown_File_Format;
00235
00236 return FT_Err_Ok;
00237 }
00238
00239
00240
00241 FT_EXPORT_DEF( FT_Error )
00242 FT_GetFile_From_Mac_ATS_Name( const char* fontName,
00243 FSSpec* pathSpec,
00244 FT_Long* face_index )
00245 {
00246 #if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
00247 ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
00248 FT_UNUSED( fontName );
00249 FT_UNUSED( pathSpec );
00250 FT_UNUSED( face_index );
00251
00252 return FT_Err_Unimplemented_Feature;
00253 #else
00254 FSRef ref;
00255 FT_Error err;
00256
00257
00258 err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
00259 if ( FT_Err_Ok != err )
00260 return err;
00261
00262 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL,
00263 pathSpec, NULL ) )
00264 return FT_Err_Unknown_File_Format;
00265
00266 return FT_Err_Ok;
00267 #endif
00268 }
00269
00270
00271 static OSErr
00272 FT_FSPathMakeRes( const UInt8* pathname,
00273 ResFileRefNum* res )
00274 {
00275 OSErr err;
00276 FSRef ref;
00277
00278
00279 if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
00280 return FT_Err_Cannot_Open_Resource;
00281
00282
00283 err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
00284 if ( noErr == err )
00285 return err;
00286
00287
00288 *res = FSOpenResFile( &ref, fsRdPerm );
00289 err = ResError();
00290
00291 return err;
00292 }
00293
00294
00295
00296 static OSType
00297 get_file_type_from_path( const UInt8* pathname )
00298 {
00299 FSRef ref;
00300 FSCatalogInfo info;
00301
00302
00303 if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
00304 return ( OSType ) 0;
00305
00306 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info,
00307 NULL, NULL, NULL ) )
00308 return ( OSType ) 0;
00309
00310 return ((FInfo *)(info.finderInfo))->fdType;
00311 }
00312
00313
00314
00315 static void
00316 create_lwfn_name( char* ps_name,
00317 Str255 lwfn_file_name )
00318 {
00319 int max = 5, count = 0;
00320 FT_Byte* p = lwfn_file_name;
00321 FT_Byte* q = (FT_Byte*)ps_name;
00322
00323
00324 lwfn_file_name[0] = 0;
00325
00326 while ( *q )
00327 {
00328 if ( ft_isupper( *q ) )
00329 {
00330 if ( count )
00331 max = 3;
00332 count = 0;
00333 }
00334 if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) )
00335 {
00336 *++p = *q;
00337 lwfn_file_name[0]++;
00338 count++;
00339 }
00340 q++;
00341 }
00342 }
00343
00344
00345 static short
00346 count_faces_sfnt( char* fond_data )
00347 {
00348
00349
00350
00351 return EndianS16_BtoN( *( (short*)( fond_data +
00352 sizeof ( FamRec ) ) ) ) + 1;
00353 }
00354
00355
00356 static short
00357 count_faces_scalable( char* fond_data )
00358 {
00359 AsscEntry* assoc;
00360 FamRec* fond;
00361 short i, face, face_all;
00362
00363
00364 fond = (FamRec*)fond_data;
00365 face_all = EndianS16_BtoN( *( (short *)( fond_data +
00366 sizeof ( FamRec ) ) ) ) + 1;
00367 assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
00368 face = 0;
00369
00370 for ( i = 0; i < face_all; i++ )
00371 {
00372 if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
00373 face++;
00374 }
00375 return face;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 static void
00388 parse_fond( char* fond_data,
00389 short* have_sfnt,
00390 ResID* sfnt_id,
00391 Str255 lwfn_file_name,
00392 short face_index )
00393 {
00394 AsscEntry* assoc;
00395 AsscEntry* base_assoc;
00396 FamRec* fond;
00397
00398
00399 *sfnt_id = 0;
00400 *have_sfnt = 0;
00401 lwfn_file_name[0] = 0;
00402
00403 fond = (FamRec*)fond_data;
00404 assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
00405 base_assoc = assoc;
00406
00407
00408 if ( 47 < face_index )
00409 return;
00410
00411
00412 if ( face_index < count_faces_sfnt( fond_data ) )
00413 {
00414 assoc += face_index;
00415
00416
00417
00418 if ( EndianS16_BtoN( assoc->fontSize ) == 0 )
00419 {
00420 *have_sfnt = 1;
00421 *sfnt_id = EndianS16_BtoN( assoc->fontID );
00422 }
00423 else if ( base_assoc->fontSize == 0 )
00424 {
00425 *have_sfnt = 1;
00426 *sfnt_id = EndianS16_BtoN( base_assoc->fontID );
00427 }
00428 }
00429
00430 if ( EndianS32_BtoN( fond->ffStylOff ) )
00431 {
00432 unsigned char* p = (unsigned char*)fond_data;
00433 StyleTable* style;
00434 unsigned short string_count;
00435 char ps_name[256];
00436 unsigned char* names[64];
00437 int i;
00438
00439
00440 p += EndianS32_BtoN( fond->ffStylOff );
00441 style = (StyleTable*)p;
00442 p += sizeof ( StyleTable );
00443 string_count = EndianS16_BtoN( *(short*)(p) );
00444 p += sizeof ( short );
00445
00446 for ( i = 0; i < string_count && i < 64; i++ )
00447 {
00448 names[i] = p;
00449 p += names[i][0];
00450 p++;
00451 }
00452
00453 {
00454 size_t ps_name_len = (size_t)names[0][0];
00455
00456
00457 if ( ps_name_len != 0 )
00458 {
00459 ft_memcpy(ps_name, names[0] + 1, ps_name_len);
00460 ps_name[ps_name_len] = 0;
00461 }
00462 if ( style->indexes[face_index] > 1 &&
00463 style->indexes[face_index] <= FT_MIN( string_count, 64 ) )
00464 {
00465 unsigned char* suffixes = names[style->indexes[face_index] - 1];
00466
00467
00468 for ( i = 1; i <= suffixes[0]; i++ )
00469 {
00470 unsigned char* s;
00471 size_t j = suffixes[i] - 1;
00472
00473
00474 if ( j < string_count && ( s = names[j] ) != NULL )
00475 {
00476 size_t s_len = (size_t)s[0];
00477
00478
00479 if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) )
00480 {
00481 ft_memcpy( ps_name + ps_name_len, s + 1, s_len );
00482 ps_name_len += s_len;
00483 ps_name[ps_name_len] = 0;
00484 }
00485 }
00486 }
00487 }
00488 }
00489
00490 create_lwfn_name( ps_name, lwfn_file_name );
00491 }
00492 }
00493
00494
00495 static FT_Error
00496 lookup_lwfn_by_fond( const UInt8* path_fond,
00497 ConstStr255Param base_lwfn,
00498 UInt8* path_lwfn,
00499 size_t path_size )
00500 {
00501 FSRef ref, par_ref;
00502 size_t dirname_len;
00503
00504
00505
00506
00507
00508 if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) )
00509 return FT_Err_Invalid_Argument;
00510
00511 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,
00512 NULL, NULL, NULL, &par_ref ) )
00513 return FT_Err_Invalid_Argument;
00514
00515 if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) )
00516 return FT_Err_Invalid_Argument;
00517
00518 if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size )
00519 return FT_Err_Invalid_Argument;
00520
00521
00522 ft_strcat( (char *)path_lwfn, "/" );
00523 dirname_len = ft_strlen( (char *)path_lwfn );
00524 ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 );
00525 path_lwfn[dirname_len + base_lwfn[0]] = '\0';
00526
00527 if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) )
00528 return FT_Err_Cannot_Open_Resource;
00529
00530 if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,
00531 NULL, NULL, NULL, NULL ) )
00532 return FT_Err_Cannot_Open_Resource;
00533
00534 return FT_Err_Ok;
00535 }
00536
00537
00538 static short
00539 count_faces( Handle fond,
00540 const UInt8* pathname )
00541 {
00542 ResID sfnt_id;
00543 short have_sfnt, have_lwfn;
00544 Str255 lwfn_file_name;
00545 UInt8 buff[PATH_MAX];
00546 FT_Error err;
00547 short num_faces;
00548
00549
00550 have_sfnt = have_lwfn = 0;
00551
00552 parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
00553
00554 if ( lwfn_file_name[0] )
00555 {
00556 err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
00557 buff, sizeof ( buff ) );
00558 if ( FT_Err_Ok == err )
00559 have_lwfn = 1;
00560 }
00561
00562 if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
00563 num_faces = 1;
00564 else
00565 num_faces = count_faces_scalable( *fond );
00566
00567 return num_faces;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576 static FT_Error
00577 read_lwfn( FT_Memory memory,
00578 ResFileRefNum res,
00579 FT_Byte** pfb_data,
00580 FT_ULong* size )
00581 {
00582 FT_Error error = FT_Err_Ok;
00583 ResID res_id;
00584 unsigned char *buffer, *p, *size_p = NULL;
00585 FT_ULong total_size = 0;
00586 FT_ULong old_total_size = 0;
00587 FT_ULong post_size, pfb_chunk_size;
00588 Handle post_data;
00589 char code, last_code;
00590
00591
00592 UseResFile( res );
00593
00594
00595
00596 res_id = 501;
00597 last_code = -1;
00598
00599 for (;;)
00600 {
00601 post_data = Get1Resource( TTAG_POST, res_id++ );
00602 if ( post_data == NULL )
00603 break;
00604
00605 code = (*post_data)[0];
00606
00607 if ( code != last_code )
00608 {
00609 if ( code == 5 )
00610 total_size += 2;
00611 else
00612 total_size += 6;
00613 }
00614
00615 total_size += GetHandleSize( post_data ) - 2;
00616 last_code = code;
00617
00618
00619 if ( total_size < old_total_size )
00620 {
00621 error = FT_Err_Array_Too_Large;
00622 goto Error;
00623 }
00624
00625 old_total_size = total_size;
00626 }
00627
00628 if ( FT_ALLOC( buffer, (FT_Long)total_size ) )
00629 goto Error;
00630
00631
00632
00633 p = buffer;
00634 res_id = 501;
00635 last_code = -1;
00636 pfb_chunk_size = 0;
00637
00638 for (;;)
00639 {
00640 post_data = Get1Resource( TTAG_POST, res_id++ );
00641 if ( post_data == NULL )
00642 break;
00643
00644 post_size = (FT_ULong)GetHandleSize( post_data ) - 2;
00645 code = (*post_data)[0];
00646
00647 if ( code != last_code )
00648 {
00649 if ( last_code != -1 )
00650 {
00651
00652 if ( size_p != NULL )
00653 {
00654 *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF );
00655 *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF );
00656 *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF );
00657 *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF );
00658 }
00659 pfb_chunk_size = 0;
00660 }
00661
00662 *p++ = 0x80;
00663 if ( code == 5 )
00664 *p++ = 0x03;
00665 else if ( code == 2 )
00666 *p++ = 0x02;
00667 else
00668 *p++ = 0x01;
00669
00670 if ( code != 5 )
00671 {
00672 size_p = p;
00673 p += 4;
00674 }
00675 }
00676
00677 ft_memcpy( p, *post_data + 2, post_size );
00678 pfb_chunk_size += post_size;
00679 p += post_size;
00680 last_code = code;
00681 }
00682
00683 *pfb_data = buffer;
00684 *size = total_size;
00685
00686 Error:
00687 CloseResFile( res );
00688 return error;
00689 }
00690
00691
00692
00693 static FT_Error
00694 FT_New_Face_From_LWFN( FT_Library library,
00695 const UInt8* pathname,
00696 FT_Long face_index,
00697 FT_Face* aface )
00698 {
00699 FT_Byte* pfb_data;
00700 FT_ULong pfb_size;
00701 FT_Error error;
00702 ResFileRefNum res;
00703
00704
00705 if ( noErr != FT_FSPathMakeRes( pathname, &res ) )
00706 return FT_Err_Cannot_Open_Resource;
00707
00708 pfb_data = NULL;
00709 pfb_size = 0;
00710 error = read_lwfn( library->memory, res, &pfb_data, &pfb_size );
00711 CloseResFile( res );
00712 if ( error )
00713 return error;
00714
00715 return open_face_from_buffer( library,
00716 pfb_data,
00717 pfb_size,
00718 face_index,
00719 "type1",
00720 aface );
00721 }
00722
00723
00724
00725 static FT_Error
00726 FT_New_Face_From_SFNT( FT_Library library,
00727 ResID sfnt_id,
00728 FT_Long face_index,
00729 FT_Face* aface )
00730 {
00731 Handle sfnt = NULL;
00732 FT_Byte* sfnt_data;
00733 size_t sfnt_size;
00734 FT_Error error = FT_Err_Ok;
00735 FT_Memory memory = library->memory;
00736 int is_cff, is_sfnt_ps;
00737
00738
00739 sfnt = GetResource( TTAG_sfnt, sfnt_id );
00740 if ( sfnt == NULL )
00741 return FT_Err_Invalid_Handle;
00742
00743 sfnt_size = (FT_ULong)GetHandleSize( sfnt );
00744 if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
00745 {
00746 ReleaseResource( sfnt );
00747 return error;
00748 }
00749
00750 ft_memcpy( sfnt_data, *sfnt, sfnt_size );
00751 ReleaseResource( sfnt );
00752
00753 is_cff = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
00754 is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 );
00755
00756 if ( is_sfnt_ps )
00757 {
00758 FT_Stream stream;
00759
00760
00761 if ( FT_NEW( stream ) )
00762 goto Try_OpenType;
00763
00764 FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );
00765 if ( !open_face_PS_from_sfnt_stream( library,
00766 stream,
00767 face_index,
00768 0, NULL,
00769 aface ) )
00770 {
00771 FT_Stream_Close( stream );
00772 FT_FREE( stream );
00773 FT_FREE( sfnt_data );
00774 goto Exit;
00775 }
00776
00777 FT_FREE( stream );
00778 }
00779 Try_OpenType:
00780 error = open_face_from_buffer( library,
00781 sfnt_data,
00782 sfnt_size,
00783 face_index,
00784 is_cff ? "cff" : "truetype",
00785 aface );
00786 Exit:
00787 return error;
00788 }
00789
00790
00791
00792 static FT_Error
00793 FT_New_Face_From_Suitcase( FT_Library library,
00794 const UInt8* pathname,
00795 FT_Long face_index,
00796 FT_Face* aface )
00797 {
00798 FT_Error error = FT_Err_Cannot_Open_Resource;
00799 ResFileRefNum res_ref;
00800 ResourceIndex res_index;
00801 Handle fond;
00802 short num_faces_in_res, num_faces_in_fond;
00803
00804
00805 if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) )
00806 return FT_Err_Cannot_Open_Resource;
00807
00808 UseResFile( res_ref );
00809 if ( ResError() )
00810 return FT_Err_Cannot_Open_Resource;
00811
00812 num_faces_in_res = 0;
00813 for ( res_index = 1; ; ++res_index )
00814 {
00815 fond = Get1IndResource( TTAG_FOND, res_index );
00816 if ( ResError() )
00817 break;
00818
00819 num_faces_in_fond = count_faces( fond, pathname );
00820 num_faces_in_res += num_faces_in_fond;
00821
00822 if ( 0 <= face_index && face_index < num_faces_in_fond && error )
00823 error = FT_New_Face_From_FOND( library, fond, face_index, aface );
00824
00825 face_index -= num_faces_in_fond;
00826 }
00827
00828 CloseResFile( res_ref );
00829 if ( FT_Err_Ok == error && NULL != aface && NULL != *aface )
00830 (*aface)->num_faces = num_faces_in_res;
00831 return error;
00832 }
00833
00834
00835
00836
00837 FT_EXPORT_DEF( FT_Error )
00838 FT_New_Face_From_FOND( FT_Library library,
00839 Handle fond,
00840 FT_Long face_index,
00841 FT_Face* aface )
00842 {
00843 short have_sfnt, have_lwfn = 0;
00844 ResID sfnt_id, fond_id;
00845 OSType fond_type;
00846 Str255 fond_name;
00847 Str255 lwfn_file_name;
00848 UInt8 path_lwfn[PATH_MAX];
00849 OSErr err;
00850 FT_Error error = FT_Err_Ok;
00851
00852
00853 GetResInfo( fond, &fond_id, &fond_type, fond_name );
00854 if ( ResError() != noErr || fond_type != TTAG_FOND )
00855 return FT_Err_Invalid_File_Format;
00856
00857 parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
00858
00859 if ( lwfn_file_name[0] )
00860 {
00861 ResFileRefNum res;
00862
00863
00864 res = HomeResFile( fond );
00865 if ( noErr != ResError() )
00866 goto found_no_lwfn_file;
00867
00868 {
00869 UInt8 path_fond[PATH_MAX];
00870 FSRef ref;
00871
00872
00873 err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum,
00874 NULL, NULL, NULL, &ref, NULL );
00875 if ( noErr != err )
00876 goto found_no_lwfn_file;
00877
00878 err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) );
00879 if ( noErr != err )
00880 goto found_no_lwfn_file;
00881
00882 error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
00883 path_lwfn, sizeof ( path_lwfn ) );
00884 if ( FT_Err_Ok == error )
00885 have_lwfn = 1;
00886 }
00887 }
00888
00889 if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
00890 error = FT_New_Face_From_LWFN( library,
00891 path_lwfn,
00892 face_index,
00893 aface );
00894 else
00895 error = FT_Err_Unknown_File_Format;
00896
00897 found_no_lwfn_file:
00898 if ( have_sfnt && FT_Err_Ok != error )
00899 error = FT_New_Face_From_SFNT( library,
00900 sfnt_id,
00901 face_index,
00902 aface );
00903
00904 return error;
00905 }
00906
00907
00908
00909 static FT_Error
00910 FT_New_Face_From_Resource( FT_Library library,
00911 const UInt8* pathname,
00912 FT_Long face_index,
00913 FT_Face* aface )
00914 {
00915 OSType file_type;
00916 FT_Error error;
00917
00918
00919
00920 file_type = get_file_type_from_path( pathname );
00921 if ( file_type == TTAG_LWFN )
00922 return FT_New_Face_From_LWFN( library, pathname, face_index, aface );
00923
00924
00925
00926
00927
00928 error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface );
00929 if ( error == 0 )
00930 return error;
00931
00932
00933
00934 *aface = NULL;
00935 return 0;
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 FT_EXPORT_DEF( FT_Error )
00951 FT_New_Face( FT_Library library,
00952 const char* pathname,
00953 FT_Long face_index,
00954 FT_Face* aface )
00955 {
00956 FT_Open_Args args;
00957 FT_Error error;
00958
00959
00960
00961 if ( !pathname )
00962 return FT_Err_Invalid_Argument;
00963
00964 error = FT_Err_Ok;
00965 *aface = NULL;
00966
00967
00968 error = FT_New_Face_From_Resource( library, (UInt8 *)pathname,
00969 face_index, aface );
00970 if ( error != 0 || *aface != NULL )
00971 return error;
00972
00973
00974 args.flags = FT_OPEN_PATHNAME;
00975 args.pathname = (char*)pathname;
00976 return FT_Open_Face( library, &args, face_index, aface );
00977 }
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 FT_EXPORT_DEF( FT_Error )
00992 FT_New_Face_From_FSRef( FT_Library library,
00993 const FSRef* ref,
00994 FT_Long face_index,
00995 FT_Face* aface )
00996 {
00997 FT_Error error;
00998 FT_Open_Args args;
00999 OSErr err;
01000 UInt8 pathname[PATH_MAX];
01001
01002
01003 if ( !ref )
01004 return FT_Err_Invalid_Argument;
01005
01006 err = FSRefMakePath( ref, pathname, sizeof ( pathname ) );
01007 if ( err )
01008 error = FT_Err_Cannot_Open_Resource;
01009
01010 error = FT_New_Face_From_Resource( library, pathname, face_index, aface );
01011 if ( error != 0 || *aface != NULL )
01012 return error;
01013
01014
01015 args.flags = FT_OPEN_PATHNAME;
01016 args.pathname = (char*)pathname;
01017 return FT_Open_Face( library, &args, face_index, aface );
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 FT_EXPORT_DEF( FT_Error )
01032 FT_New_Face_From_FSSpec( FT_Library library,
01033 const FSSpec* spec,
01034 FT_Long face_index,
01035 FT_Face* aface )
01036 {
01037 #if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
01038 ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
01039 FT_UNUSED( library );
01040 FT_UNUSED( spec );
01041 FT_UNUSED( face_index );
01042 FT_UNUSED( aface );
01043
01044 return FT_Err_Unimplemented_Feature;
01045 #else
01046 FSRef ref;
01047
01048
01049 if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr )
01050 return FT_Err_Invalid_Argument;
01051 else
01052 return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
01053 #endif
01054 }
01055
01056
01057