📄 ftmac.c
字号:
/* we're done adding a chunk, fill in the size field */ *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF ); *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF ); pfb_chunk_size = 0; } *p++ = 0x80; if ( code == 5 ) *p++ = 0x03; /* the end */ else if ( code == 2 ) *p++ = 0x02; /* binary segment */ else *p++ = 0x01; /* ASCII segment */ if ( code != 5 ) { size_p = p; /* save for later */ p += 4; /* make space for size field */ } } memcpy( p, *post_data + 2, post_size ); pfb_chunk_size += post_size; p += post_size; last_code = code; } *pfb_data = buffer; *size = total_size; Error: CloseResFile( res_ref ); return error; } /* Finalizer for a memory stream; gets called by FT_Done_Face(). It frees the memory it uses. */ static void memory_stream_close( FT_Stream stream ) { FT_Memory memory = stream->memory; 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_Close 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 ( ALLOC( stream, sizeof ( *stream ) ) ) goto Exit; FT_New_Memory_Stream( library, base, size, stream ); 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 ) { 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; else { FT_Done_Stream( stream ); FREE( 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; FT_Memory memory = library->memory; error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size ); if ( error ) return error;#if 0 { FILE* f; char* path; path = p2c_str( spec->name ); strcat( path, ".PFB" ); f = fopen( path, "wb" ); if ( f ) { fwrite( pfb_data, 1, pfb_size, f ); fclose( f ); } }#endif 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_Stream stream = NULL; FT_Error error = 0; FT_Memory memory = library->memory; sfnt = GetResource( 'sfnt', sfnt_id ); if ( ResError() ) return FT_Err_Invalid_Handle; sfnt_size = (FT_ULong)GetHandleSize( sfnt ); if ( ALLOC( sfnt_data, (FT_Long)sfnt_size ) ) { ReleaseResource( sfnt ); return error; } HLock( sfnt ); memcpy( sfnt_data, *sfnt, sfnt_size ); HUnlock( sfnt ); ReleaseResource( sfnt ); return open_face_from_buffer( library, sfnt_data, sfnt_size, face_index, "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; } /* documentation 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; FT_Error error = FT_Err_Unknown_File_Format; 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 ); 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; } /*************************************************************************/ /* */ /* <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; file_type = get_file_type( &spec ); if ( file_type == 'FFIL' || file_type == 'tfil' ) return FT_New_Face_From_Suitcase( library, &spec, face_index, aface ); else if ( file_type == 'LWFN' ) return FT_New_Face_From_LWFN( library, &spec, face_index, aface ); else { 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 + -