00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_STREAM_H
00022 #include FT_TRUETYPE_TAGS_H
00023 #include "ttbdf.h"
00024
00025 #include "sferrors.h"
00026
00027
00028 #ifdef TT_CONFIG_OPTION_BDF
00029
00030
00031
00032
00033
00034
00035
00036 #undef FT_COMPONENT
00037 #define FT_COMPONENT trace_ttbdf
00038
00039
00040 FT_LOCAL_DEF( void )
00041 tt_face_free_bdf_props( TT_Face face )
00042 {
00043 TT_BDF bdf = &face->bdf;
00044
00045
00046 if ( bdf->loaded )
00047 {
00048 FT_Stream stream = FT_FACE(face)->stream;
00049
00050
00051 if ( bdf->table != NULL )
00052 FT_FRAME_RELEASE( bdf->table );
00053
00054 bdf->table_end = NULL;
00055 bdf->strings = NULL;
00056 bdf->strings_size = 0;
00057 }
00058 }
00059
00060
00061 static FT_Error
00062 tt_face_load_bdf_props( TT_Face face,
00063 FT_Stream stream )
00064 {
00065 TT_BDF bdf = &face->bdf;
00066 FT_ULong length;
00067 FT_Error error;
00068
00069
00070 FT_ZERO( bdf );
00071
00072 error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
00073 if ( error ||
00074 length < 8 ||
00075 FT_FRAME_EXTRACT( length, bdf->table ) )
00076 {
00077 error = FT_Err_Invalid_Table;
00078 goto Exit;
00079 }
00080
00081 bdf->table_end = bdf->table + length;
00082
00083 {
00084 FT_Byte* p = bdf->table;
00085 FT_UInt version = FT_NEXT_USHORT( p );
00086 FT_UInt num_strikes = FT_NEXT_USHORT( p );
00087 FT_ULong strings = FT_NEXT_ULONG ( p );
00088 FT_UInt count;
00089 FT_Byte* strike;
00090
00091
00092 if ( version != 0x0001 ||
00093 strings < 8 ||
00094 ( strings - 8 ) / 4 < num_strikes ||
00095 strings + 1 > length )
00096 {
00097 goto BadTable;
00098 }
00099
00100 bdf->num_strikes = num_strikes;
00101 bdf->strings = bdf->table + strings;
00102 bdf->strings_size = length - strings;
00103
00104 count = bdf->num_strikes;
00105 p = bdf->table + 8;
00106 strike = p + count * 4;
00107
00108
00109 for ( ; count > 0; count-- )
00110 {
00111 FT_UInt num_items = FT_PEEK_USHORT( p + 2 );
00112
00113
00114
00115
00116
00117 strike += 10 * num_items;
00118
00119 p += 4;
00120 }
00121
00122 if ( strike > bdf->strings )
00123 goto BadTable;
00124 }
00125
00126 bdf->loaded = 1;
00127
00128 Exit:
00129 return error;
00130
00131 BadTable:
00132 FT_FRAME_RELEASE( bdf->table );
00133 FT_ZERO( bdf );
00134 error = FT_Err_Invalid_Table;
00135 goto Exit;
00136 }
00137
00138
00139 FT_LOCAL_DEF( FT_Error )
00140 tt_face_find_bdf_prop( TT_Face face,
00141 const char* property_name,
00142 BDF_PropertyRec *aprop )
00143 {
00144 TT_BDF bdf = &face->bdf;
00145 FT_Size size = FT_FACE(face)->size;
00146 FT_Error error = 0;
00147 FT_Byte* p;
00148 FT_UInt count;
00149 FT_Byte* strike;
00150 FT_Offset property_len;
00151
00152
00153 aprop->type = BDF_PROPERTY_TYPE_NONE;
00154
00155 if ( bdf->loaded == 0 )
00156 {
00157 error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
00158 if ( error )
00159 goto Exit;
00160 }
00161
00162 count = bdf->num_strikes;
00163 p = bdf->table + 8;
00164 strike = p + 4 * count;
00165
00166 error = FT_Err_Invalid_Argument;
00167
00168 if ( size == NULL || property_name == NULL )
00169 goto Exit;
00170
00171 property_len = ft_strlen( property_name );
00172 if ( property_len == 0 )
00173 goto Exit;
00174
00175 for ( ; count > 0; count-- )
00176 {
00177 FT_UInt _ppem = FT_NEXT_USHORT( p );
00178 FT_UInt _count = FT_NEXT_USHORT( p );
00179
00180 if ( _ppem == size->metrics.y_ppem )
00181 {
00182 count = _count;
00183 goto FoundStrike;
00184 }
00185
00186 strike += 10 * _count;
00187 }
00188 goto Exit;
00189
00190 FoundStrike:
00191 p = strike;
00192 for ( ; count > 0; count-- )
00193 {
00194 FT_UInt type = FT_PEEK_USHORT( p + 4 );
00195
00196 if ( ( type & 0x10 ) != 0 )
00197 {
00198 FT_UInt32 name_offset = FT_PEEK_ULONG( p );
00199 FT_UInt32 value = FT_PEEK_ULONG( p + 6 );
00200
00201
00202 if ( name_offset < bdf->strings_size &&
00203 property_len < bdf->strings_size - name_offset &&
00204 ft_strncmp( property_name,
00205 (const char*)bdf->strings + name_offset,
00206 bdf->strings_size - name_offset ) == 0 )
00207 {
00208 switch ( type & 0x0F )
00209 {
00210 case 0x00:
00211 case 0x01:
00212
00213 if ( value < bdf->strings_size &&
00214 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
00215 {
00216 aprop->type = BDF_PROPERTY_TYPE_ATOM;
00217 aprop->u.atom = (const char*)bdf->strings + value;
00218 error = 0;
00219 goto Exit;
00220 }
00221 break;
00222
00223 case 0x02:
00224 aprop->type = BDF_PROPERTY_TYPE_INTEGER;
00225 aprop->u.integer = (FT_Int32)value;
00226 error = 0;
00227 goto Exit;
00228
00229 case 0x03:
00230 aprop->type = BDF_PROPERTY_TYPE_CARDINAL;
00231 aprop->u.cardinal = value;
00232 error = 0;
00233 goto Exit;
00234
00235 default:
00236 ;
00237 }
00238 }
00239 }
00240 p += 10;
00241 }
00242
00243 Exit:
00244 return error;
00245 }
00246
00247 #endif
00248
00249
00250