*** orig/t1afm.c 2004-07-31 21:40:22.000000000 -0700 --- t1afm.c 2004-08-01 13:13:06.000000000 -0700 *************** *** 33,40 **** FT_LOCAL_DEF( void ) ! T1_Done_AFM( FT_Memory memory, ! T1_AFM* afm ) { FT_FREE( afm->kern_pairs ); afm->num_pairs = 0; --- 33,40 ---- FT_LOCAL_DEF( void ) ! T1_Done_Metrics( FT_Memory memory, ! T1_AFM* afm ) { FT_FREE( afm->kern_pairs ); afm->num_pairs = 0; *************** *** 153,163 **** /* parse an AFM file -- for now, only read the kerning pairs */ ! FT_LOCAL_DEF( FT_Error ) T1_Read_AFM( FT_Face t1_face, FT_Stream stream ) { ! FT_Error error; FT_Memory memory = stream->memory; FT_Byte* start; FT_Byte* limit; --- 153,163 ---- /* parse an AFM file -- for now, only read the kerning pairs */ ! static FT_Error T1_Read_AFM( FT_Face t1_face, FT_Stream stream ) { ! FT_Error error = 0; FT_Memory memory = stream->memory; FT_Byte* start; FT_Byte* limit; *************** *** 168,176 **** T1_AFM* afm = 0; - if ( FT_FRAME_ENTER( stream->size ) ) - return error; - start = (FT_Byte*)stream->cursor; limit = (FT_Byte*)stream->limit; p = start; --- 168,173 ---- *************** *** 233,244 **** if ( error ) FT_FREE( afm ); ! FT_FRAME_EXIT(); return error; } /* find the kerning for a given glyph pair */ FT_LOCAL_DEF( void ) T1_Get_Kerning( T1_AFM* afm, --- 230,394 ---- if ( error ) FT_FREE( afm ); ! return error; ! } ! ! #define LITTLE_ENDIAN_USHORT(p) ((p)[0]|((p)[1]<<8)) ! #define LITTLE_ENDIAN_INT(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) ! ! /* parse an AFM file -- for now, only read the kerning pairs */ ! static FT_Error ! T1_Read_PFM( FT_Face t1_face, ! FT_Stream stream ) ! { ! FT_Error error = 0; ! FT_Memory memory = stream->memory; ! FT_Byte* start; ! FT_Byte* limit; ! FT_Byte* p; ! FT_Int kern_count = 0; ! T1_Kern_Pair* pair; ! T1_AFM* afm = 0; ! FT_Int width_table_length; ! FT_CharMap oldcharmap; ! FT_CharMap charmap; ! FT_Int n; ! ! ! start = (FT_Byte*)stream->cursor; ! limit = (FT_Byte*)stream->limit; ! p = start; ! ! /* Figure out how long the width table is */ ! /* This info is a little-endian short at offset 99 */ ! p = start + 99; ! if ( p+2 > limit ) ! { ! error = T1_Err_Unknown_File_Format; ! goto Exit; ! } ! width_table_length = LITTLE_ENDIAN_USHORT(p); ! ! p += 18 + width_table_length; ! if ( p+0x12 > limit || LITTLE_ENDIAN_USHORT(p) < 0x12 ) ! /* Extension table is probably optional */ ! goto Exit; ! /* Kerning offset is 14 bytes from start of extensions table */ ! p += 14; ! p = start + LITTLE_ENDIAN_INT(p); ! if ( p+2 > limit ) ! { ! error = T1_Err_Unknown_File_Format; ! goto Exit; ! } ! ! kern_count = LITTLE_ENDIAN_USHORT(p); ! p += 2; ! if ( p+4*kern_count > limit ) ! { ! error = T1_Err_Unknown_File_Format; ! goto Exit; ! } ! ! /* Actually, kerning pairs are simply optional! */ ! if ( kern_count == 0 ) ! goto Exit; ! ! /* allocate the pairs */ ! if ( FT_NEW( afm ) || FT_NEW_ARRAY( afm->kern_pairs, kern_count ) ) ! goto Exit; ! ! /* save in face object */ ! ((T1_Face)t1_face)->afm_data = afm; ! ! t1_face->face_flags |= FT_FACE_FLAG_KERNING; ! ! /* now, read each kern pair */ ! pair = afm->kern_pairs; ! afm->num_pairs = kern_count; ! limit = p + 4*kern_count; ! ! /* PFM kerning data are stored by encoding rather than glyph index */ ! /* So find the postscript charmap of this font and install it */ ! /* temporarily. */ ! /* If we find no PostScript charmap, then just use the default and */ ! /* hope */ ! oldcharmap = t1_face->charmap; ! charmap = NULL; ! for ( n = 0; n < t1_face->num_charmaps; n++ ) ! { ! charmap = t1_face->charmaps[n]; ! if ( charmap->platform_id == 7 /* PostScript psuedo platform */ ) ! { ! error = FT_Set_Charmap( t1_face, charmap ); ! if ( error ) ! goto Exit; ! break; ! } ! } ! ! /* Kerning info is stored as: */ ! /* encoding of first glyph (1 byte) */ ! /* encoding of second glyph (1 byte) */ ! /* offset (little-endian short) */ ! for ( ; p < limit ; p+=4 ) ! { ! pair->glyph1 = FT_Get_Char_Index( t1_face, p[0] ); ! pair->glyph2 = FT_Get_Char_Index( t1_face, p[1] ); ! pair->kerning.x = (short) LITTLE_ENDIAN_USHORT(p+2); ! ! pair->kerning.y = 0; ! ! pair++; ! } ! ! if ( oldcharmap != NULL ) ! error = FT_Set_Charmap( t1_face, oldcharmap ); ! if ( error ) ! goto Exit; ! ! /* now, sort the kern pairs according to their glyph indices */ ! ft_qsort( afm->kern_pairs, kern_count, sizeof ( T1_Kern_Pair ), ! compare_kern_pairs ); ! ! Exit: ! if ( error ) ! FT_FREE( afm ); return error; } + /* parse a metrics file -- either AFM or PFM depending on what */ + /* it turns out to be */ + FT_LOCAL_DEF( FT_Error ) + T1_Read_Metrics( FT_Face t1_face, + FT_Stream stream ) + { + FT_Error error; + FT_Byte* start; + + + if ( FT_FRAME_ENTER( stream->size ) ) + return error; + + start = (FT_Byte*)stream->cursor; + + if ( stream->size>=ft_strlen("StartFontMetrics") && + ft_strncmp(start,"StartFontMetrics",ft_strlen("StartFontMetrics"))==0 ) + error = T1_Read_AFM( t1_face, stream ); + else if ( stream->size>6 && + start[0]==0x00 && start[1]==0x01 && + LITTLE_ENDIAN_INT(start+2)==stream->size ) + error = T1_Read_PFM( t1_face, stream ); + else + error = T1_Err_Unknown_File_Format; + + FT_FRAME_EXIT(); + + return error; + } + /* find the kerning for a given glyph pair */ FT_LOCAL_DEF( void ) T1_Get_Kerning( T1_AFM* afm, *** orig/t1afm.h 2004-07-31 21:40:22.000000000 -0700 --- t1afm.h 2004-08-01 13:13:06.000000000 -0700 *************** *** 44,55 **** FT_LOCAL( FT_Error ) ! T1_Read_AFM( FT_Face face, ! FT_Stream stream ); FT_LOCAL( void ) ! T1_Done_AFM( FT_Memory memory, ! T1_AFM* afm ); FT_LOCAL( void ) T1_Get_Kerning( T1_AFM* afm, --- 44,55 ---- FT_LOCAL( FT_Error ) ! T1_Read_Metrics( FT_Face face, ! FT_Stream stream ); FT_LOCAL( void ) ! T1_Done_Metrics( FT_Memory memory, ! T1_AFM* afm ); FT_LOCAL( void ) T1_Get_Kerning( T1_AFM* afm, *** orig/t1driver.c 2004-07-31 21:40:22.000000000 -0700 --- t1driver.c 2004-07-31 21:58:25.000000000 -0700 *************** *** 294,300 **** (FT_Face_AttachFunc) 0, #else (FT_Face_GetKerningFunc) Get_Kerning, ! (FT_Face_AttachFunc) T1_Read_AFM, #endif (FT_Face_GetAdvancesFunc) 0 }; --- 294,300 ---- (FT_Face_AttachFunc) 0, #else (FT_Face_GetKerningFunc) Get_Kerning, ! (FT_Face_AttachFunc) T1_Read_Metrics, #endif (FT_Face_GetAdvancesFunc) 0 }; *** orig/t1objs.c 2004-07-31 21:40:22.000000000 -0700 --- t1objs.c 2004-08-01 13:13:06.000000000 -0700 *************** *** 233,239 **** #ifndef T1_CONFIG_OPTION_NO_AFM /* release afm data if present */ if ( face->afm_data ) ! T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); #endif /* release unicode map, if any */ --- 233,239 ---- #ifndef T1_CONFIG_OPTION_NO_AFM /* release afm data if present */ if ( face->afm_data ) ! T1_Done_Metrics( memory, (T1_AFM*)face->afm_data ); #endif /* release unicode map, if any */