?? ftoldmac.c
字號(hào):
/****************************************************************************/
/* */
/* The FreeType project -- a free and portable quality TrueType renderer. */
/* */
/* Copyright 1996-2000, 2003, 2004, 2005, 2006 by */
/* suzuki toshiya, D. Turner, R.Wilhelm, and W. Lemberg */
/* */
/* */
/* ftoldmac - test program for MacOS specific API in ftmac.c */
/* */
/* */
/****************************************************************************/
#if defined(__GNUC__) && defined(__APPLE_CC__)
# include <Carbon/Carbon.h>
# include <ApplicationServices/ApplicationServices.h>
# include <stdint.h>
# include <sys/param.h>
#else
# include <ConditionalMacros.h>
# include <Files.h>
# include <Fonts.h>
#endif
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_IDS_H
/* the following header shouldn't be used in normal programs */
#include FT_INTERNAL_DEBUG_H
/* showing driver name */
#include FT_MODULE_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DRIVER_H
#include FT_MAC_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum
{
FT_OldMac_Err_Unimplemented,
FT_OldMac_Err_TooLongFileName,
FT_OldMac_Err_FileNotFound,
FT_OldMac_Err_UnresolvableFontName,
FT_OldMac_Err_PseudoFontName,
FT_OldMac_Err_UnswappableFontID,
FT_OldMac_Err_TooLargeFaceIndex,
FT_OldMac_Err_Ok = 0
} FT_OldMac_Err;
/* statics of font scanning */
int num_scanned_fonts;
int num_opened_fonts;
int num_scanned_faces;
int num_opened_faces;
/* setting for face scanning */
int max_face_number;
Boolean force_scan_face;
char* font_listing_api;
char* font_resolve_api;
Boolean auto_suffix;
void initParamBlock( CInfoPBRec*, Str255 );
void dumpPBErr( CInfoPBRec* );
void crawlDir( CInfoPBRec*, char* );
void crawlFontFile( char* );
OSErr ftmac_FSPathMakeSpec( const UInt8*, FSSpec*, Boolean );
OSErr ftmac_FSpMakePath( const FSSpec*, UInt8*, UInt32 );
OSErr
ftmac_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;
}
void
dump_face_info( FT_Face face )
{
printf( "\t\tface_index=%d, face_flags=0x%08x, num_glyphs=%d\n",
(int)face->face_index,
(unsigned int)(face->face_flags),
(int)face->num_glyphs );
printf( "\t\tnum_fixed_sizes=%d, style_flags=%d%d%d%d%d%d\n",
face->num_fixed_sizes,
( (unsigned int)(face->style_flags) >> 5 ) & 1,
( (unsigned int)(face->style_flags) >> 4 ) & 1,
( (unsigned int)(face->style_flags) >> 3 ) & 1,
( (unsigned int)(face->style_flags) >> 2 ) & 1,
( (unsigned int)(face->style_flags) >> 1 ) & 1,
( (unsigned int)(face->style_flags) ) & 1
);
printf("\t\tfamily_name=[%s], style_name=[%s]\n",
face->family_name, face->style_name );
}
void
crawlFontFile( char* font_file_path )
{
FT_Library library;
FT_Face face;
int i, j;
FSSpec spec;
printf( "*** check font file [%s]\n", font_file_path );
if ( 0 != FT_Init_FreeType( &library ) )
{
printf( "\tError: Could not initialize FreeType\n" );
return;
}
if ( noErr != ftmac_FSPathMakeSpec( (unsigned char const *)font_file_path, &spec, FALSE ) )
{
printf( "\tError: Could not open File (MacOS API)\n" );
return;
}
face = NULL;
num_scanned_fonts ++;
if ( 0 != FT_New_Face_From_FSSpec( library, &spec, 0, &face ) )
{
printf( "\tError: Could not open File (FreeType API)\n" );
return;
}
num_opened_fonts ++;
printf( "\tFont file has %d face\n", (int)face->num_faces );
j = face->num_faces + max_face_number;
for ( i = 0; i < j; i++ )
{
num_scanned_faces ++;
printf( "\tCheck Face #%d...", i );
if ( 0 == FT_New_Face_From_FSSpec( library, &spec, i, &face ) )
{
num_opened_faces ++;
printf( "Ok\n" );
dump_face_info( face );
FT_Done_Face( face );
}
else
{
printf( "Failed\n" );
if ( !force_scan_face )
goto no_more_face;
}
}
no_more_face:
FT_Done_FreeType( library );
}
void
crawlDir( CInfoPBRec* ci_pb_dir,
char* dir_path )
{
CInfoPBRec ci_pb;
char file_full_path[1024];
int dirname_len;
int i;
printf( "ioVRefNum = 0x%04x, ioDrDirID = 0x%08x, ioDrParID= 0x%08x\n",
ci_pb_dir->dirInfo.ioVRefNum,
(unsigned int) ci_pb_dir->dirInfo.ioDrParID,
(unsigned int) ci_pb_dir->dirInfo.ioDrDirID );
printf( "files in directory: %d\n", ci_pb_dir->dirInfo.ioDrNmFls );
dirname_len = strlen( dir_path );
strcpy( file_full_path, dir_path );
if ( 0 < dirname_len && ':' != file_full_path[ dirname_len - 1 ] )
dirname_len ++;
file_full_path[ dirname_len - 1 ] = ':';
for ( i = 0; i <= ci_pb_dir->dirInfo.ioDrNmFls; i ++ )
{
Str255 fileName;
memset( &ci_pb, 0, sizeof( CInfoPBRec ) );
fileName[0] = 0;
ci_pb.hFileInfo.ioVRefNum = ci_pb_dir->dirInfo.ioVRefNum;
ci_pb.hFileInfo.ioDirID = ci_pb_dir->dirInfo.ioDrDirID;
ci_pb.hFileInfo.ioNamePtr = fileName;
ci_pb.hFileInfo.ioFDirIndex = i;
if ( noErr == PBGetCatInfoSync( &ci_pb ) )
{
if ( NULL != ci_pb.hFileInfo.ioNamePtr )
{
char file_name[256];
strncpy( file_name, (char *)ci_pb.hFileInfo.ioNamePtr + 1, ci_pb.hFileInfo.ioNamePtr[0] );
file_name[ ci_pb.hFileInfo.ioNamePtr[0] ] = '\0';
if ( 0 == strcmp( ".DS_Store", file_name ) )
printf( "*** known non-font filename [%s]\n", file_name );
else if ( 0 == ( ci_pb.hFileInfo.ioFlAttrib & ioDirMask ) )
{
file_full_path[ dirname_len ] = '\0';
strncat( file_full_path, file_name, sizeof( file_full_path ) );
crawlFontFile( file_full_path );
}
}
}
}
}
void
initParamBlock( CInfoPBRec* paramBlock,
Str255 fileName )
{
paramBlock->hFileInfo.ioCompletion = 0; /* synch calls */
paramBlock->hFileInfo.ioNamePtr = fileName;
paramBlock->hFileInfo.ioVRefNum = 0; /* alias for default */
paramBlock->hFileInfo.ioFDirIndex = 0; /* XXX */
paramBlock->hFileInfo.ioDirID = 0; /* alias for default */
}
void
dumpPBErr( CInfoPBRec* paramBlock )
{
printf( "[PB access returned after " );
switch ( paramBlock->hFileInfo.ioResult )
{
case ioErr:
printf( "I/O Error" );
break;
case fnOpnErr:
printf( "File not Open Error" );
break;
case nsvErr:
printf( "No such volume Error" );
break;
case fnfErr:
printf( "File not found Error" );
break;
case rfNumErr:
printf( "Bad reference number Error" );
break;
default:
printf( "unexpected err=%d", paramBlock->hFileInfo.ioResult );
break;
}
printf( "]\n" );
}
OSErr
ftmac_FSPathMakeSpec( const UInt8* pathname,
FSSpec* spec_p,
Boolean isDirectory )
{
const char *p, *q;
short vRefNum;
long dirID;
Str255 nodeName;
OSErr err;
FT_UNUSED( isDirectory );
p = q = (const char *)pathname;
dirID = 0;
vRefNum = 0;
while ( 1 )
{
q = p + FT_MIN( 255, ft_strlen( (char const *)p ) );
if ( q == p )
return 0;
if ( 255 < ft_strlen( (char const *)pathname ) )
{
while ( p < q && *q != ':' )
q--;
}
if ( p < q )
nodeName[0] = q - p;
else if ( ft_strlen( (char const *)p ) < 256 )
nodeName[0] = ft_strlen( p );
else
return errFSNameTooLong;
strncpy( (char *)nodeName + 1, (char *)p, nodeName[0] );
nodeName[ nodeName[0] + 1 ] = '\0';
err = FSMakeFSSpec( vRefNum, dirID, nodeName, spec_p );
if ( err || '\0' == *q )
return err;
vRefNum = spec_p->vRefNum;
dirID = spec_p->parID;
p = q + 1;
}
}
void
test_font_files( int argc,
char** argv )
{
int i;
for ( i = 1; i < argc; i++ )
{
OSErr status;
CInfoPBRec paramBlock;
Str255 fileName;
/* XXX: should be skipped by better argument handler */
if ( '-' == argv[i][0] && '-' == argv[i][1] )
continue;
/* XXX: restrict pathname to legacy HFS limit for simplicity */
if ( 254 < strlen( argv[i] ) )
continue;
fileName[0] = strlen( argv[i] );
memcpy( fileName + 1, argv[i], fileName[0] );
initParamBlock( ¶mBlock, fileName );
status = PBGetCatInfoSync( ¶mBlock );
if ( 0 > status )
printf( "[PB access failed] error = %d\n", status );
{
FSSpec spec;
Str255 volName;
int i;
strncpy( (char *)volName, (char *)fileName, fileName[0] );
printf( "given file name [%s]", fileName + 1 );
for ( i = 1; i < fileName[0] && ':' != fileName[i + 1]; i ++ )
;
volName[i + 1] = ':';
volName[i + 2] = '\0';
volName[0] = i + 1;
printf( "-> volume name [%s]", volName + 1 );
status = FSMakeFSSpec( 0, 0, volName, &spec);
if ( noErr != status )
printf( "FSMakeFSSpec(%s) error %d\n", volName, status );
else
{
printf( "FSMakeFSSpec(%s) return volID = 0x%08x\n", volName + 1, spec.vRefNum );
paramBlock.hFileInfo.ioVRefNum = spec.vRefNum;
}
}
if ( 0 != paramBlock.hFileInfo.ioResult )
dumpPBErr( ¶mBlock );
else if ( 0 != ( paramBlock.hFileInfo.ioFlAttrib & ioDirMask ) )
crawlDir( ¶mBlock, argv[i] );
else
crawlFontFile( argv[i] );
}
}
void
print_help()
{
printf("\n" );
printf(" ftoldmac [pathname in HFS syntax]\n" );
printf("\n" );
printf(" e.g. \"Macintosh HD:System Folder:Fonts:\"\n" );
printf(" quotation is required to avoid shell expansion\n" );
printf(" scan directory and open all font files in there\n" );
printf("\n" );
printf(" --max-face-number=N\n" );
printf(" scan face until N instead of face->num_faces\n" );
printf("\n" );
printf(" --force-scan-face\n" );
printf(" ignore the error to open face and continue to max face number\n" );
printf("\n" );
printf(" ftoldmac --font-listing-api=XXX --font-resolve-api=YYY\n" );
printf("\n" );
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -