/* * gcc -DFT2_BUILD_LIBRARY -I../../include -o test_afm test_afm.c \ * -L../../objs/.libs -lfreetype -lz -static */ #include #include FT_FREETYPE_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_POSTSCRIPT_AUX_H void dump_fontinfo( AFM_FontInfo fi ) { FT_Int i; printf( "This AFM is for %sCID font.\n\n", ( fi->IsCIDFont ) ? "" : "non-" ); printf( "FontBBox: %.2f %.2f %.2f %.2f\n", fi->FontBBox.xMin / 65536., fi->FontBBox.yMin / 65536., fi->FontBBox.xMax / 65536., fi->FontBBox.yMax / 65536. ); printf( "Ascender: %.2f\n", fi->Ascender / 65536. ); printf( "Descender: %.2f\n\n", fi->Descender / 65536. ); if ( fi->NumTrackKern ) printf( "There are %d sets of track kernings:\n", fi->NumTrackKern ); else printf( "There is no track kerning.\n" ); for ( i = 0; i < fi->NumTrackKern; i++ ) { AFM_TrackKern tk = fi->TrackKerns + i; printf( "\t%2d: %5.2f %5.2f %5.2f %5.2f\n", tk->degree, tk->min_ptsize / 65536., tk->min_kern / 65536., tk->max_ptsize / 65536., tk->max_kern / 65536. ); } printf( "\n" ); if ( fi->NumKernPair ) printf( "There are %d kerning pairs:\n", fi->NumKernPair ); else printf( "There is no kerning pair.\n" ); for ( i = 0; i < fi->NumKernPair; i++ ) { AFM_KernPair kp = fi->KernPairs + i; printf( "\t%3d + %3d => (%4d, %4d)\n", kp->index1, kp->index2, kp->x, kp->y ); } } int dummy_get_index( const char* name, FT_UInt len, void* user_data ) { if ( len ) return name[0]; else return 0; } FT_Error parse_afm( FT_Library library, FT_Stream stream, AFM_FontInfo fi ) { PSAux_Service psaux; AFM_ParserRec parser; FT_Error error = FT_Err_Ok; psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" ); if ( !psaux || !psaux->afm_parser_funcs ) return -1; error = FT_Stream_EnterFrame( stream, stream->size ); if ( error ) return error; error = psaux->afm_parser_funcs->init( &parser, library->memory, stream->cursor, stream->limit ); if ( error ) return error; parser.FontInfo = fi; parser.get_index = dummy_get_index; error = psaux->afm_parser_funcs->parse( &parser ); psaux->afm_parser_funcs->done( &parser ); return error; } int main( int argc, char** argv ) { FT_Library library; FT_StreamRec stream; FT_Error error = FT_Err_Ok; AFM_FontInfoRec fi; if ( argc < 2 ) return FT_Err_Invalid_Argument; error = FT_Init_FreeType( &library ); if ( error ) return error; FT_ZERO( &stream ); error = FT_Stream_Open( &stream, argv[1] ); if ( error ) goto Exit; stream.memory = library->memory; FT_ZERO( &fi ); error = parse_afm( library, &stream, &fi ); if ( !error ) { FT_Memory memory = library->memory; dump_fontinfo( &fi ); if ( fi.KernPairs ) FT_FREE( fi.KernPairs ); if ( fi.TrackKerns ) FT_FREE( fi.TrackKerns ); } else printf( "parse error\n" ); FT_Stream_Close( &stream ); Exit: FT_Done_FreeType( library ); return error; }