00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "gxvmort.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037 #undef FT_COMPONENT
00038 #define FT_COMPONENT trace_gxvmort
00039
00040
00041 typedef struct GXV_mort_subtable_type1_StateOptRec_
00042 {
00043 FT_UShort substitutionTable;
00044 FT_UShort substitutionTable_length;
00045
00046 } GXV_mort_subtable_type1_StateOptRec,
00047 *GXV_mort_subtable_type1_StateOptRecData;
00048
00049 #define GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE \
00050 ( GXV_STATETABLE_HEADER_SIZE + 2 )
00051
00052
00053 static void
00054 gxv_mort_subtable_type1_substitutionTable_load( FT_Bytes table,
00055 FT_Bytes limit,
00056 GXV_Validator valid )
00057 {
00058 FT_Bytes p = table;
00059
00060 GXV_mort_subtable_type1_StateOptRecData optdata =
00061 (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata;
00062
00063
00064 GXV_LIMIT_CHECK( 2 );
00065 optdata->substitutionTable = FT_NEXT_USHORT( p );
00066 }
00067
00068
00069 static void
00070 gxv_mort_subtable_type1_subtable_setup( FT_UShort table_size,
00071 FT_UShort classTable,
00072 FT_UShort stateArray,
00073 FT_UShort entryTable,
00074 FT_UShort* classTable_length_p,
00075 FT_UShort* stateArray_length_p,
00076 FT_UShort* entryTable_length_p,
00077 GXV_Validator valid )
00078 {
00079 FT_UShort o[4];
00080 FT_UShort *l[4];
00081 FT_UShort buff[5];
00082
00083 GXV_mort_subtable_type1_StateOptRecData optdata =
00084 (GXV_mort_subtable_type1_StateOptRecData)valid->statetable.optdata;
00085
00086
00087 o[0] = classTable;
00088 o[1] = stateArray;
00089 o[2] = entryTable;
00090 o[3] = optdata->substitutionTable;
00091 l[0] = classTable_length_p;
00092 l[1] = stateArray_length_p;
00093 l[2] = entryTable_length_p;
00094 l[3] = &( optdata->substitutionTable_length );
00095
00096 gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid );
00097 }
00098
00099
00100 static void
00101 gxv_mort_subtable_type1_offset_to_subst_validate(
00102 FT_Short wordOffset,
00103 const FT_String* tag,
00104 FT_Byte state,
00105 GXV_Validator valid )
00106 {
00107 FT_UShort substTable;
00108 FT_UShort substTable_limit;
00109 FT_UShort min_gid;
00110 FT_UShort max_gid;
00111
00112 FT_UNUSED( tag );
00113 FT_UNUSED( state );
00114
00115
00116 substTable =
00117 ((GXV_mort_subtable_type1_StateOptRec *)
00118 (valid->statetable.optdata))->substitutionTable;
00119 substTable_limit =
00120 (FT_UShort)( substTable +
00121 ((GXV_mort_subtable_type1_StateOptRec *)
00122 (valid->statetable.optdata))->substitutionTable_length );
00123
00124 min_gid = (FT_UShort)( ( substTable - wordOffset * 2 ) / 2 );
00125 max_gid = (FT_UShort)( ( substTable_limit - wordOffset * 2 ) / 2 );
00126 max_gid = (FT_UShort)( FT_MAX( max_gid, valid->face->num_glyphs ) );
00127
00128
00129
00130
00131 }
00132
00133
00134 static void
00135 gxv_mort_subtable_type1_entry_validate(
00136 FT_Byte state,
00137 FT_UShort flags,
00138 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
00139 FT_Bytes table,
00140 FT_Bytes limit,
00141 GXV_Validator valid )
00142 {
00143 FT_UShort setMark;
00144 FT_UShort dontAdvance;
00145 FT_UShort reserved;
00146 FT_Short markOffset;
00147 FT_Short currentOffset;
00148
00149 FT_UNUSED( table );
00150 FT_UNUSED( limit );
00151
00152
00153 setMark = (FT_UShort)( flags >> 15 );
00154 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
00155 reserved = (FT_Short)( flags & 0x3FFF );
00156
00157 markOffset = (FT_Short)( glyphOffset_p->ul >> 16 );
00158 currentOffset = (FT_Short)( glyphOffset_p->ul );
00159
00160 if ( 0 < reserved )
00161 {
00162 GXV_TRACE(( " non-zero bits found in reserved range\n" ));
00163 if ( valid->root->level >= FT_VALIDATE_PARANOID )
00164 FT_INVALID_DATA;
00165 }
00166
00167 gxv_mort_subtable_type1_offset_to_subst_validate( markOffset,
00168 "markOffset",
00169 state,
00170 valid );
00171
00172 gxv_mort_subtable_type1_offset_to_subst_validate( currentOffset,
00173 "currentOffset",
00174 state,
00175 valid );
00176 }
00177
00178
00179 static void
00180 gxv_mort_subtable_type1_substTable_validate( FT_Bytes table,
00181 FT_Bytes limit,
00182 GXV_Validator valid )
00183 {
00184 FT_Bytes p = table;
00185 FT_UShort num_gids = (FT_UShort)(
00186 ((GXV_mort_subtable_type1_StateOptRec *)
00187 (valid->statetable.optdata))->substitutionTable_length / 2 );
00188 FT_UShort i;
00189
00190
00191 GXV_NAME_ENTER( "validating contents of substitutionTable" );
00192 for ( i = 0; i < num_gids ; i ++ )
00193 {
00194 FT_UShort dst_gid;
00195
00196
00197 GXV_LIMIT_CHECK( 2 );
00198 dst_gid = FT_NEXT_USHORT( p );
00199
00200 if ( dst_gid >= 0xFFFFU )
00201 continue;
00202
00203 if ( dst_gid > valid->face->num_glyphs )
00204 {
00205 GXV_TRACE(( "substTable include too large gid[%d]=%d >"
00206 " max defined gid #%d\n",
00207 i, dst_gid, valid->face->num_glyphs ));
00208 if ( valid->root->level >= FT_VALIDATE_PARANOID )
00209 FT_INVALID_GLYPH_ID;
00210 }
00211 }
00212
00213 GXV_EXIT;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222 FT_LOCAL_DEF( void )
00223 gxv_mort_subtable_type1_validate( FT_Bytes table,
00224 FT_Bytes limit,
00225 GXV_Validator valid )
00226 {
00227 FT_Bytes p = table;
00228
00229 GXV_mort_subtable_type1_StateOptRec st_rec;
00230
00231
00232 GXV_NAME_ENTER( "mort chain subtable type1 (Contextual Glyph Subst)" );
00233
00234 GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE1_HEADER_SIZE );
00235
00236 valid->statetable.optdata =
00237 &st_rec;
00238 valid->statetable.optdata_load_func =
00239 gxv_mort_subtable_type1_substitutionTable_load;
00240 valid->statetable.subtable_setup_func =
00241 gxv_mort_subtable_type1_subtable_setup;
00242 valid->statetable.entry_glyphoffset_fmt =
00243 GXV_GLYPHOFFSET_ULONG;
00244 valid->statetable.entry_validate_func =
00245
00246 gxv_mort_subtable_type1_entry_validate;
00247 gxv_StateTable_validate( p, limit, valid );
00248
00249 gxv_mort_subtable_type1_substTable_validate(
00250 table + st_rec.substitutionTable,
00251 table + st_rec.substitutionTable + st_rec.substitutionTable_length,
00252 valid );
00253
00254 GXV_EXIT;
00255 }
00256
00257
00258