static short count_faces_sfnt( char* fond_data ) { /* The count is 1 greater than the value in the FOND. */ /* Isn't that cute? :-) */ return EndianS16_BtoN( *( (short*)( fond_data + sizeof ( FamRec ) ) ) ) + 1; }
static short count_faces_scalable( char* fond_data ) { AsscEntry* assoc; short i, face, face_all; face_all = EndianS16_BtoN( *( (short *)( fond_data + sizeof ( FamRec ) ) ) ) + 1; assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); face = 0; for ( i = 0; i < face_all; i++ ) { if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) ) face++; } return face; }
static void parse_fond( char* fond_data, short* have_sfnt, ResID* sfnt_id, Str255 lwfn_file_name, short face_index ) { AsscEntry* assoc; AsscEntry* base_assoc; FamRec* fond; *sfnt_id = 0; *have_sfnt = 0; lwfn_file_name[0] = 0; fond = (FamRec*)fond_data; assoc = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 ); base_assoc = assoc; /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */ if ( 47 < face_index ) return; /* Let's do a little range checking before we get too excited here */ if ( face_index < count_faces_sfnt( fond_data ) ) { assoc += face_index; /* add on the face_index! */ /* if the face at this index is not scalable, fall back to the first one (old behavior) */ if ( EndianS16_BtoN( assoc->fontSize ) == 0 ) { *have_sfnt = 1; *sfnt_id = EndianS16_BtoN( assoc->fontID ); } else if ( base_assoc->fontSize == 0 ) { *have_sfnt = 1; *sfnt_id = EndianS16_BtoN( base_assoc->fontID ); } } if ( EndianS32_BtoN( fond->ffStylOff ) ) { unsigned char* p = (unsigned char*)fond_data; StyleTable* style; unsigned short string_count; char ps_name[256]; unsigned char* names[64]; int i; p += EndianS32_BtoN( fond->ffStylOff ); style = (StyleTable*)p; p += sizeof ( StyleTable ); string_count = EndianS16_BtoN( *(short*)(p) ); p += sizeof ( short ); for ( i = 0; i < string_count && i < 64; i++ ) { names[i] = p; p += names[i][0]; p++; } { size_t ps_name_len = (size_t)names[0][0]; if ( ps_name_len != 0 ) { ft_memcpy(ps_name, names[0] + 1, ps_name_len); ps_name[ps_name_len] = 0; } if ( style->indexes[face_index] > 1 && style->indexes[face_index] <= FT_MIN( string_count, 64 ) ) { unsigned char* suffixes = names[style->indexes[face_index] - 1]; for ( i = 1; i <= suffixes[0]; i++ ) { unsigned char* s; size_t j = suffixes[i] - 1; if ( j < string_count && ( s = names[j] ) != NULL ) { size_t s_len = (size_t)s[0]; if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) ) { ft_memcpy( ps_name + ps_name_len, s + 1, s_len ); ps_name_len += s_len; ps_name[ps_name_len] = 0; } } } } } create_lwfn_name( ps_name, lwfn_file_name ); } }