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 "gxvmorx.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037 #undef FT_COMPONENT
00038 #define FT_COMPONENT trace_gxvmorx
00039
00040
00041 typedef struct GXV_morx_subtable_type1_StateOptRec_
00042 {
00043 FT_ULong substitutionTable;
00044 FT_ULong substitutionTable_length;
00045 FT_UShort substitutionTable_num_lookupTables;
00046
00047 } GXV_morx_subtable_type1_StateOptRec,
00048 *GXV_morx_subtable_type1_StateOptRecData;
00049
00050
00051 #define GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE \
00052 ( GXV_STATETABLE_HEADER_SIZE + 2 )
00053
00054
00055 static void
00056 gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes table,
00057 FT_Bytes limit,
00058 GXV_Validator valid )
00059 {
00060 FT_Bytes p = table;
00061
00062 GXV_morx_subtable_type1_StateOptRecData optdata =
00063 (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00064
00065
00066 GXV_LIMIT_CHECK( 2 );
00067 optdata->substitutionTable = FT_NEXT_USHORT( p );
00068 }
00069
00070
00071 static void
00072 gxv_morx_subtable_type1_subtable_setup( FT_ULong table_size,
00073 FT_ULong classTable,
00074 FT_ULong stateArray,
00075 FT_ULong entryTable,
00076 FT_ULong* classTable_length_p,
00077 FT_ULong* stateArray_length_p,
00078 FT_ULong* entryTable_length_p,
00079 GXV_Validator valid )
00080 {
00081 FT_ULong o[4];
00082 FT_ULong *l[4];
00083 FT_ULong buff[5];
00084
00085 GXV_morx_subtable_type1_StateOptRecData optdata =
00086 (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00087
00088
00089 o[0] = classTable;
00090 o[1] = stateArray;
00091 o[2] = entryTable;
00092 o[3] = optdata->substitutionTable;
00093 l[0] = classTable_length_p;
00094 l[1] = stateArray_length_p;
00095 l[2] = entryTable_length_p;
00096 l[3] = &(optdata->substitutionTable_length);
00097
00098 gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, valid );
00099 }
00100
00101
00102 static void
00103 gxv_morx_subtable_type1_entry_validate(
00104 FT_UShort state,
00105 FT_UShort flags,
00106 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
00107 FT_Bytes table,
00108 FT_Bytes limit,
00109 GXV_Validator valid )
00110 {
00111 FT_UShort setMark;
00112 FT_UShort dontAdvance;
00113 FT_UShort reserved;
00114 FT_Short markIndex;
00115 FT_Short currentIndex;
00116
00117 GXV_morx_subtable_type1_StateOptRecData optdata =
00118 (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00119
00120 FT_UNUSED( state );
00121 FT_UNUSED( table );
00122 FT_UNUSED( limit );
00123
00124
00125 setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
00126 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
00127
00128 reserved = (FT_UShort)( flags & 0x3FFF );
00129
00130 markIndex = (FT_Short)( glyphOffset_p->ul >> 16 );
00131 currentIndex = (FT_Short)( glyphOffset_p->ul );
00132
00133 GXV_TRACE(( " setMark=%01d dontAdvance=%01d\n",
00134 setMark, dontAdvance ));
00135
00136 if ( 0 < reserved )
00137 {
00138 GXV_TRACE(( " non-zero bits found in reserved range\n" ));
00139 if ( valid->root->level >= FT_VALIDATE_PARANOID )
00140 FT_INVALID_DATA;
00141 }
00142
00143 GXV_TRACE(( "markIndex = %d, currentIndex = %d\n",
00144 markIndex, currentIndex ));
00145
00146 if ( optdata->substitutionTable_num_lookupTables < markIndex + 1 )
00147 optdata->substitutionTable_num_lookupTables =
00148 (FT_Short)( markIndex + 1 );
00149
00150 if ( optdata->substitutionTable_num_lookupTables < currentIndex + 1 )
00151 optdata->substitutionTable_num_lookupTables =
00152 (FT_Short)( currentIndex + 1 );
00153 }
00154
00155
00156 static void
00157 gxv_morx_subtable_type1_LookupValue_validate( FT_UShort glyph,
00158 GXV_LookupValueCPtr value_p,
00159 GXV_Validator valid )
00160 {
00161 FT_UNUSED( glyph );
00162
00163 GXV_TRACE(( "morx subtable type1 subst.: %d -> %d\n", glyph, value_p->u ));
00164
00165 if ( value_p->u > valid->face->num_glyphs )
00166 FT_INVALID_GLYPH_ID;
00167 }
00168
00169
00170 static GXV_LookupValueDesc
00171 gxv_morx_subtable_type1_LookupFmt4_transit(
00172 FT_UShort relative_gindex,
00173 GXV_LookupValueCPtr base_value_p,
00174 FT_Bytes lookuptbl_limit,
00175 GXV_Validator valid )
00176 {
00177 FT_Bytes p;
00178 FT_Bytes limit;
00179 FT_UShort offset;
00180 GXV_LookupValueDesc value;
00181
00182
00183 offset = (FT_UShort)( base_value_p->u +
00184 relative_gindex * sizeof ( FT_UShort ) );
00185
00186 p = valid->lookuptbl_head + offset;
00187 limit = lookuptbl_limit;
00188
00189 GXV_LIMIT_CHECK ( 2 );
00190 value.u = FT_NEXT_USHORT( p );
00191
00192 return value;
00193 }
00194
00195
00196
00197
00198
00199 static void
00200 gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes table,
00201 FT_Bytes limit,
00202 GXV_Validator valid )
00203 {
00204 FT_Bytes p = table;
00205 FT_UShort i;
00206
00207 GXV_morx_subtable_type1_StateOptRecData optdata =
00208 (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata;
00209
00210
00211
00212 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
00213 valid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate;
00214 valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit;
00215
00216 for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ )
00217 {
00218 FT_ULong offset;
00219
00220
00221 GXV_LIMIT_CHECK( 4 );
00222 offset = FT_NEXT_ULONG( p );
00223
00224 gxv_LookupTable_validate( table + offset, limit, valid );
00225 }
00226
00227
00228 }
00229
00230
00231
00232
00233
00234
00235
00236 FT_LOCAL_DEF( void )
00237 gxv_morx_subtable_type1_validate( FT_Bytes table,
00238 FT_Bytes limit,
00239 GXV_Validator valid )
00240 {
00241 FT_Bytes p = table;
00242
00243 GXV_morx_subtable_type1_StateOptRec st_rec;
00244
00245
00246 GXV_NAME_ENTER( "morx chain subtable type1 (Contextual Glyph Subst)" );
00247
00248 GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE );
00249
00250 st_rec.substitutionTable_num_lookupTables = 0;
00251
00252 valid->xstatetable.optdata =
00253 &st_rec;
00254 valid->xstatetable.optdata_load_func =
00255 gxv_morx_subtable_type1_substitutionTable_load;
00256 valid->xstatetable.subtable_setup_func =
00257 gxv_morx_subtable_type1_subtable_setup;
00258 valid->xstatetable.entry_glyphoffset_fmt =
00259 GXV_GLYPHOFFSET_ULONG;
00260 valid->xstatetable.entry_validate_func =
00261 gxv_morx_subtable_type1_entry_validate;
00262
00263 gxv_XStateTable_validate( p, limit, valid );
00264
00265 gxv_morx_subtable_type1_substitutionTable_validate(
00266 table + st_rec.substitutionTable,
00267 table + st_rec.substitutionTable + st_rec.substitutionTable_length,
00268 valid );
00269
00270 GXV_EXIT;
00271 }
00272
00273
00274