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( (const char*)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_UINT( start + 2 ) == stream->size ) error = T1_Read_PFM( t1_face, stream ); else error = T1_Err_Unknown_File_Format; FT_FRAME_EXIT(); return error; }
T1_Read_Metrics( FT_Face t1_face, FT_Stream stream ) { PSAux_Service psaux; FT_Memory memory = stream->memory; AFM_ParserRec parser; AFM_FontInfo fi = NULL; FT_Error error = FT_ERR( Unknown_File_Format ); T1_Font t1_font = &( (T1_Face)t1_face )->type1; if ( FT_NEW( fi ) || FT_FRAME_ENTER( stream->size ) ) goto Exit; fi->FontBBox = t1_font->font_bbox; fi->Ascender = t1_font->font_bbox.yMax; fi->Descender = t1_font->font_bbox.yMin; psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; if ( psaux->afm_parser_funcs ) { error = psaux->afm_parser_funcs->init( &parser, stream->memory, stream->cursor, stream->limit ); if ( !error ) { parser.FontInfo = fi; parser.get_index = t1_get_index; parser.user_data = t1_font; error = psaux->afm_parser_funcs->parse( &parser ); psaux->afm_parser_funcs->done( &parser ); } } if ( FT_ERR_EQ( error, Unknown_File_Format ) ) { FT_Byte* start = stream->cursor; /* MS Windows allows versions up to 0x3FF without complaining */ if ( stream->size > 6 && start[1] < 4 && FT_PEEK_ULONG_LE( start + 2 ) == stream->size ) error = T1_Read_PFM( t1_face, stream, fi ); } if ( !error ) { t1_font->font_bbox = fi->FontBBox; t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; /* no `U' suffix here to 0xFFFF! */ t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16; t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16; /* no `U' suffix here to 0x8000! */ t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000 ) >> 16 ); t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 ); if ( fi->NumKernPair ) { t1_face->face_flags |= FT_FACE_FLAG_KERNING; ( (T1_Face)t1_face )->afm_data = fi; fi = NULL; } }
T1_Read_Metrics( FT_Face t1_face, FT_Stream stream ) { PSAux_Service psaux; FT_Memory memory = stream->memory; AFM_ParserRec parser; AFM_FontInfo fi; FT_Error error = T1_Err_Unknown_File_Format; T1_Font t1_font = &( (T1_Face)t1_face )->type1; if ( FT_NEW( fi ) ) return error; if ( FT_FRAME_ENTER( stream->size ) ) { FT_FREE( fi ); return error; } fi->FontBBox = t1_font->font_bbox; fi->Ascender = t1_font->font_bbox.yMax; fi->Descender = t1_font->font_bbox.yMin; psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; if ( psaux && psaux->afm_parser_funcs ) { error = psaux->afm_parser_funcs->init( &parser, stream->memory, stream->cursor, stream->limit ); if ( !error ) { parser.FontInfo = fi; parser.get_index = t1_get_index; parser.user_data = t1_font; error = psaux->afm_parser_funcs->parse( &parser ); psaux->afm_parser_funcs->done( &parser ); } } if ( error == T1_Err_Unknown_File_Format ) { FT_Byte* start = stream->cursor; if ( stream->size > 6 && start[0] == 0x00 && start[1] == 0x01 && FT_PEEK_ULONG_LE( start + 2 ) == stream->size ) error = T1_Read_PFM( t1_face, stream, fi ); } if ( !error ) { t1_font->font_bbox = fi->FontBBox; t1_face->bbox.xMin = fi->FontBBox.xMin >> 16; t1_face->bbox.yMin = fi->FontBBox.yMin >> 16; t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFFU ) >> 16; t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFFU ) >> 16; t1_face->ascender = (FT_Short)( ( fi->Ascender + 0x8000U ) >> 16 ); t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000U ) >> 16 ); if ( fi->NumKernPair ) { t1_face->face_flags |= FT_FACE_FLAG_KERNING; ( (T1_Face)t1_face )->afm_data = fi; } }