?? ftmac.c
字號(hào):
/***************************************************************************//* *//* ftmac.c *//* *//* Mac FOND support. Written by just@letterror.com. *//* Heavily Fixed by mpsuzuki, George Williams and Sean McBride *//* *//* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by *//* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. *//* *//* This file is part of the FreeType project, and may only be used, *//* modified, and distributed under the terms of the FreeType project *//* license, LICENSE.TXT. By continuing to use, modify, or distribute *//* this file you indicate that you have read the license and *//* understand and accept it fully. *//* *//***************************************************************************/ /* Notes Mac suitcase files can (and often do!) contain multiple fonts. To support this I use the face_index argument of FT_(Open|New)_Face() functions, and pretend the suitcase file is a collection. Warning: fbit and NFNT bitmap resources are not supported yet. In old sfnt fonts, bitmap glyph data for each size is stored in each `NFNT' resources instead of the `bdat' table in the sfnt resource. Therefore, face->num_fixed_sizes is set to 0, because bitmap data in `NFNT' resource is unavailable at present. The Mac FOND support works roughly like this: - Check whether the offered stream points to a Mac suitcase file. This is done by checking the file type: it has to be 'FFIL' or 'tfil'. The stream that gets passed to our init_face() routine is a stdio stream, which isn't usable for us, since the FOND resources live in the resource fork. So we just grab the stream->pathname field. - Read the FOND resource into memory, then check whether there is a TrueType font and/or(!) a Type 1 font available. - If there is a Type 1 font available (as a separate `LWFN' file), read its data into memory, massage it slightly so it becomes PFB data, wrap it into a memory stream, load the Type 1 driver and delegate the rest of the work to it by calling FT_Open_Face(). (XXX TODO: after this has been done, the kerning data from the FOND resource should be appended to the face: On the Mac there are usually no AFM files available. However, this is tricky since we need to map Mac char codes to ps glyph names to glyph ID's...) - If there is a TrueType font (an `sfnt' resource), read it into memory, wrap it into a memory stream, load the TrueType driver and delegate the rest of the work to it, by calling FT_Open_Face(). */#include <ft2build.h>#include FT_FREETYPE_H#include FT_INTERNAL_STREAM_H#if defined( __GNUC__ ) || defined( __IBMC__ ) /* This is for Mac OS X. Without redefinition, OS_INLINE */ /* expands to `static inline' which doesn't survive the */ /* -ansi compilation flag of GCC. */#define OS_INLINE static __inline__#include <Carbon/Carbon.h>#else#include <Resources.h>#include <Fonts.h>#include <Errors.h>#include <Files.h>#include <TextUtils.h>#endif#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO#include <FSp_fopen.h>#endif#include FT_MAC_H /* FSSpec functions are deprecated since Mac OS X 10.4 */#ifndef HAVE_FSSPEC#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON#define HAVE_FSSPEC 1#else#define HAVE_FSSPEC 0#endif#endif /* most FSRef functions were introduced since Mac OS 9 */#ifndef HAVE_FSREF#if TARGET_API_MAC_OSX#define HAVE_FSREF 1#else#define HAVE_FSREF 0#endif#endif#ifndef HFS_MAXPATHLEN#define HFS_MAXPATHLEN 1024#endif /* QuickDraw is deprecated since Mac OS X 10.4 */#ifndef HAVE_QUICKDRAW_CARBON#if TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON#define HAVE_QUICKDRAW_CARBON 1#else#define HAVE_QUICKDRAW_CARBON 0#endif#endif /* AppleTypeService is available since Mac OS X */#ifndef HAVE_ATS#if TARGET_API_MAC_OSX#define HAVE_ATS 1#else#define HAVE_ATS 0#endif#endif /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over TrueType in case *both* are available (this is not common, but it *is* possible). */#ifndef PREFER_LWFN#define PREFER_LWFN 1#endif#if !HAVE_QUICKDRAW_CARBON /* QuickDraw is deprecated since Mac OS X 10.4 */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, FT_Long* face_index ) { return FT_Err_Unimplemented_Feature; }#else FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, FSSpec* pathSpec, FT_Long* face_index ) { OptionBits options = kFMUseGlobalScopeOption; FMFontFamilyIterator famIter; OSStatus status = FMCreateFontFamilyIterator( NULL, NULL, options, &famIter ); FMFont the_font = 0; FMFontFamily family = 0; *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 ) ft_strcat( fullName, " Bold" ); if ( style & italic ) ft_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; }#endif /* HAVE_QUICKDRAW_CARBON */#if !HAVE_ATS FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, FSSpec* pathSpec, FT_Long* face_index ) { return FT_Err_Unimplemented_Feature; }#else FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_ATS_Name( const char* fontName, FSSpec* pathSpec, FT_Long* face_index ) { CFStringRef cf_fontName; ATSFontRef ats_font_id; *face_index = 0; cf_fontName = CFStringCreateWithCString( NULL, fontName, kCFStringEncodingMacRoman ); ats_font_id = ATSFontFindFromName( cf_fontName, kATSOptionFlagsUnRestrictedScope ); if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL ) return FT_Err_Unknown_File_Format; if ( 0 != ATSFontGetFileSpecification( ats_font_id, pathSpec ) ) return FT_Err_Unknown_File_Format; /* face_index calculation by searching preceding fontIDs */ /* with same FSRef */ { int i; FSSpec f; for ( i = 1; i < ats_font_id; i++ ) { if ( 0 != ATSFontGetFileSpecification( ats_font_id - i, &f ) || f.vRefNum != pathSpec->vRefNum || f.parID != pathSpec->parID || f.name[0] != pathSpec->name[0] || 0 != ft_strncmp( (char *)f.name + 1, (char *)pathSpec->name + 1, f.name[0] ) ) break; } *face_index = ( i - 1 ); } return FT_Err_Ok; }#endif /* HAVE_ATS */#if defined( __MWERKS__ ) && !TARGET_RT_MAC_MACHO#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) FT_CALLBACK_DEF( void ) ft_FSp_stream_close( FT_Stream stream ) { ft_fclose( STREAM_FILE( stream ) ); stream->descriptor.pointer = NULL; stream->size = 0; stream->base = 0; } FT_CALLBACK_DEF( unsigned long ) ft_FSp_stream_io( FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count ) { FT_FILE* file; file = STREAM_FILE( stream ); ft_fseek( file, offset, SEEK_SET ); return (unsigned long)ft_fread( buffer, 1, count, file ); }#endif /* __MWERKS__ && !TARGET_RT_MAC_MACHO */#if HAVE_FSSPEC && !HAVE_FSREF static OSErr FT_FSPathMakeSpec( const UInt8* pathname, FSSpec* spec_p, Boolean isDirectory ) { const char *p, *q; short vRefNum; long dirID; Str255 nodeName; OSErr err; p = q = (const char *)pathname; dirID = 0; vRefNum = 0; while ( 1 ) { q = p + FT_MIN( 255, ft_strlen( p ) ); if ( q == p ) return 0; if ( 255 < ft_strlen( (char *)pathname ) ) { while ( p < q && *q != ':' ) q--; } if ( p < q ) *(char *)nodeName = q - p; else if ( ft_strlen( p ) < 256 ) *(char *)nodeName = ft_strlen( p ); else return errFSNameTooLong; ft_strncpy( (char *)nodeName + 1, (char *)p, *(char *)nodeName ); err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p ); if ( err || '\0' == *q ) return err; vRefNum = spec_p->vRefNum; dirID = spec_p->parID; p = q; } } static OSErr FT_FSpMakePath( const FSSpec* spec_p, UInt8* path, UInt32 maxPathSize ) { OSErr err; FSSpec spec = *spec_p; short vRefNum; long dirID; Str255 parDir_name; FT_MEM_SET( path, 0, maxPathSize ); while ( 1 ) { int child_namelen = ft_strlen( (char *)path ); unsigned char node_namelen = spec.name[0]; unsigned char* node_name = spec.name + 1; if ( node_namelen + child_namelen > maxPathSize ) return errFSNameTooLong; FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen ); FT_MEM_COPY( path, node_name, node_namelen ); if ( child_namelen > 0 ) path[node_namelen] = ':'; vRefNum = spec.vRefNum; dirID = spec.parID; parDir_name[0] = '\0'; err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec ); if ( noErr != err || dirID == spec.parID ) break; } return noErr; }#endif /* HAVE_FSSPEC && !HAVE_FSREF */ static OSErr FT_FSPathMakeRes( const UInt8* pathname, short* res ) {#if HAVE_FSREF OSErr err; FSRef ref; if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) return FT_Err_Cannot_Open_Resource; /* at present, no support for dfont format */ err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res ); if ( noErr == err ) return err; /* fallback to original resource-fork font */ *res = FSOpenResFile( &ref, fsRdPerm ); err = ResError();#else OSErr err; FSSpec spec; if ( noErr != FT_FSPathMakeSpec( pathname, &spec, FALSE ) ) return FT_Err_Cannot_Open_Resource; /* at present, no support for dfont format without FSRef */ /* (see above), try original resource-fork font */ *res = FSpOpenResFile( &spec, fsRdPerm ); err = ResError();#endif /* HAVE_FSREF */ return err; } /* Return the file type for given pathname */ static OSType get_file_type_from_path( const UInt8* pathname ) {#if HAVE_FSREF FSRef ref; FSCatalogInfo info; if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) ) return ( OSType ) 0; if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info, NULL, NULL, NULL ) )
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -