📄 ftmac.c
字号:
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 ); } error = FT_Open_Face( library, &args, face_index, aface ); if ( error == FT_Err_Ok ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; return error; } /* Create a new FT_Face from a file spec to an LWFN file. */ static FT_Error FT_New_Face_From_LWFN( FT_Library library, FSSpec* spec, FT_Long face_index, FT_Face *aface ) { FT_Byte* pfb_data; FT_ULong pfb_size; FT_Error error; error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size ); if ( error ) return error; return open_face_from_buffer( library, pfb_data, pfb_size, face_index, "type1", aface ); } /* 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, FT_Long face_index, FT_Face *aface ) { Handle sfnt = NULL; FT_Byte* sfnt_data; size_t sfnt_size; FT_Error error = 0; FT_Memory memory = library->memory; int is_cff; sfnt = GetResource( 'sfnt', sfnt_id ); if ( ResError() ) return FT_Err_Invalid_Handle; sfnt_size = (FT_ULong)GetHandleSize( sfnt ); if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) { ReleaseResource( sfnt ); return error; } HLock( sfnt ); ft_memcpy( sfnt_data, *sfnt, sfnt_size ); HUnlock( sfnt ); ReleaseResource( sfnt ); is_cff = sfnt_size > 4 && sfnt_data[0] == 'O' && sfnt_data[1] == 'T' && sfnt_data[2] == 'T' && sfnt_data[3] == 'O'; return open_face_from_buffer( library, sfnt_data, sfnt_size, face_index, is_cff ? "cff" : "truetype", aface ); } /* Create a new FT_Face from a file spec to a suitcase file. */ static FT_Error FT_New_Face_From_Suitcase( FT_Library library, FSSpec* spec, FT_Long face_index, FT_Face *aface ) { FT_Error error = FT_Err_Ok; short res_ref, res_index; Handle fond; res_ref = FSpOpenResFile( spec, fsRdPerm ); if ( ResError() ) return FT_Err_Cannot_Open_Resource; UseResFile( res_ref ); /* face_index may be -1, in which case we just need to do a sanity check */ if ( face_index < 0 ) res_index = 1; else { res_index = (short)( face_index + 1 ); face_index = 0; } fond = Get1IndResource( 'FOND', res_index ); if ( ResError() ) { error = FT_Err_Cannot_Open_Resource; goto Error; } error = FT_New_Face_From_FOND( library, fond, face_index, aface ); Error: CloseResFile( res_ref ); return error; }#ifdef TARGET_API_MAC_CARBON /* Create a new FT_Face from a file spec to a suitcase file. */ static FT_Error FT_New_Face_From_dfont( FT_Library library, FSSpec* spec, FT_Long face_index, FT_Face* aface ) { FT_Error error = FT_Err_Ok; short res_ref, res_index; Handle fond; FSRef hostContainerRef; error = FSpMakeFSRef( spec, &hostContainerRef ); if ( error == noErr ) error = FSOpenResourceFile( &hostContainerRef, 0, NULL, fsRdPerm, &res_ref ); if ( error != noErr ) return FT_Err_Cannot_Open_Resource; UseResFile( res_ref ); /* face_index may be -1, in which case we just need to do a sanity check */ if ( face_index < 0 ) res_index = 1; else { res_index = (short)( face_index + 1 ); face_index = 0; } fond = Get1IndResource( 'FOND', res_index ); if ( ResError() ) { error = FT_Err_Cannot_Open_Resource; goto Error; } error = FT_New_Face_From_FOND( library, fond, face_index, aface ); Error: CloseResFile( res_ref ); return error; }#endif /* documentation is in ftmac.h */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FOND( FT_Library library, Handle fond, FT_Long face_index, FT_Face *aface ) { short sfnt_id, have_sfnt, have_lwfn = 0; Str255 lwfn_file_name; short fond_id; OSType fond_type; Str255 fond_name; FSSpec lwfn_spec; GetResInfo( fond, &fond_id, &fond_type, fond_name ); if ( ResError() != noErr || fond_type != 'FOND' ) return FT_Err_Invalid_File_Format; HLock( fond ); parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); HUnlock( fond ); if ( lwfn_file_name[0] ) { if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok ) have_lwfn = 1; /* yeah, we got one! */ else have_lwfn = 0; /* no LWFN file found */ } if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) return FT_New_Face_From_LWFN( library, &lwfn_spec, face_index, aface ); else if ( have_sfnt ) return FT_New_Face_From_SFNT( library, sfnt_id, face_index, aface ); return FT_Err_Unknown_File_Format; } /* documentation is in ftmac.h */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( char* fontName, FSSpec* pathSpec, FT_Long* face_index ) { OptionBits options = kFMUseGlobalScopeOption; FMFontFamilyIterator famIter; OSStatus status = FMCreateFontFamilyIterator( NULL, NULL, options, &famIter ); FMFont the_font = NULL; FMFontFamily family = NULL; *face_index = 0; while ( status == 0 && !the_font ) { status = FMGetNextFontFamily( &famIter, &family ); if ( status == 0 ) { int stat2; FMFontFamilyInstanceIterator instIter; Str255 famNameStr; char famName[256]; /* get the family name */ FMGetFontFamilyName( family, famNameStr ); CopyPascalStringToC( famNameStr, famName ); /* iterate through the styles */ FMCreateFontFamilyInstanceIterator( family, &instIter ); *face_index = 0; stat2 = 0; while ( stat2 == 0 && !the_font ) { FMFontStyle style; FMFontSize size; FMFont font; stat2 = FMGetNextFontFamilyInstance( &instIter, &font, &style, &size ); if ( stat2 == 0 && size == 0 ) { char fullName[256]; /* build up a complete face name */ ft_strcpy( fullName, famName ); if ( style & bold ) strcat( fullName, " Bold" ); if ( style & italic ) strcat( fullName, " Italic" ); /* compare with the name we are looking for */ if ( ft_strcmp( fullName, fontName ) == 0 ) { /* found it! */ the_font = font; } else ++(*face_index); } } FMDisposeFontFamilyInstanceIterator( &instIter ); } } FMDisposeFontFamilyIterator( &famIter ); if ( the_font ) { FMGetFontContainer( the_font, pathSpec ); return FT_Err_Ok; } else return FT_Err_Unknown_File_Format; } static long ResourceForkSize(FSSpec* spec) { long len; short refNum; OSErr e; e = FSpOpenRF( spec, fsRdPerm, &refNum ); /* I.M. Files 2-155 */ if ( e == noErr ) { e = GetEOF( refNum, &len ); FSClose( refNum ); } return ( e == noErr ) ? len : 0; } /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Face */ /* */ /* <Description> */ /* This is the Mac-specific implementation of FT_New_Face. In */ /* addition to the standard FT_New_Face() functionality, it also */ /* accepts pathnames to Mac suitcase files. For further */ /* documentation see the original FT_New_Face() in freetype.h. */ /* */ FT_EXPORT_DEF( FT_Error ) FT_New_Face( FT_Library library, const char* pathname, FT_Long face_index, FT_Face *aface ) { FT_Open_Args args; FSSpec spec; OSType file_type; /* test for valid `library' and `aface' delayed to FT_Open_Face() */ if ( !pathname ) return FT_Err_Invalid_Argument; if ( file_spec_from_path( pathname, &spec ) ) return FT_Err_Invalid_Argument; /* Regardless of type, don't try to use the resource fork if it is */ /* empty. Some TTF fonts have type `FFIL', for example, but they */ /* only have data forks. */ if ( ResourceForkSize( &spec ) != 0 ) { file_type = get_file_type( &spec ); if ( file_type == 'FFIL' || file_type == 'tfil' ) return FT_New_Face_From_Suitcase( library, &spec, face_index, aface ); if ( file_type == 'LWFN' ) return FT_New_Face_From_LWFN( library, &spec, face_index, aface ); }#ifdef TARGET_API_MAC_CARBON if ( is_dfont( &spec ) ) return FT_New_Face_From_dfont( library, &spec, face_index, aface );#endif /* let it fall through to normal loader (.ttf, .otf, etc.) */ args.flags = FT_OPEN_PATHNAME; args.pathname = (char*)pathname; return FT_Open_Face( library, &args, face_index, aface ); }/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -