Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengxvmort.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* gxvmort.c */ 00004 /* */ 00005 /* TrueTypeGX/AAT mort table validation (body). */ 00006 /* */ 00007 /* Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 /***************************************************************************/ 00019 /* */ 00020 /* gxvalid is derived from both gxlayout module and otvalid module. */ 00021 /* Development of gxlayout is supported by the Information-technology */ 00022 /* Promotion Agency(IPA), Japan. */ 00023 /* */ 00024 /***************************************************************************/ 00025 00026 00027 #include "gxvmort.h" 00028 #include "gxvfeat.h" 00029 00030 00031 /*************************************************************************/ 00032 /* */ 00033 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00034 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00035 /* messages during execution. */ 00036 /* */ 00037 #undef FT_COMPONENT 00038 #define FT_COMPONENT trace_gxvmort 00039 00040 00041 static void 00042 gxv_mort_feature_validate( GXV_mort_feature f, 00043 GXV_Validator valid ) 00044 { 00045 if ( f->featureType >= gxv_feat_registry_length ) 00046 { 00047 GXV_TRACE(( "featureType %d is out of registered range, " 00048 "setting %d is unchecked\n", 00049 f->featureType, f->featureSetting )); 00050 if ( valid->root->level >= FT_VALIDATE_PARANOID ) 00051 FT_INVALID_DATA; 00052 } 00053 else if ( !gxv_feat_registry[f->featureType].existence ) 00054 { 00055 GXV_TRACE(( "featureType %d is within registered area " 00056 "but undefined, setting %d is unchecked\n", 00057 f->featureType, f->featureSetting )); 00058 if ( valid->root->level >= FT_VALIDATE_PARANOID ) 00059 FT_INVALID_DATA; 00060 } 00061 else 00062 { 00063 FT_Byte nSettings_max; 00064 00065 00066 /* nSettings in gxvfeat.c is halved for exclusive on/off settings */ 00067 nSettings_max = gxv_feat_registry[f->featureType].nSettings; 00068 if ( gxv_feat_registry[f->featureType].exclusive ) 00069 nSettings_max = (FT_Byte)( 2 * nSettings_max ); 00070 00071 GXV_TRACE(( "featureType %d is registered", f->featureType )); 00072 GXV_TRACE(( "setting %d", f->featureSetting )); 00073 00074 if ( f->featureSetting > nSettings_max ) 00075 { 00076 GXV_TRACE(( "out of defined range %d", nSettings_max )); 00077 if ( valid->root->level >= FT_VALIDATE_PARANOID ) 00078 FT_INVALID_DATA; 00079 } 00080 GXV_TRACE(( "\n" )); 00081 } 00082 00083 /* TODO: enableFlags must be unique value in specified chain? */ 00084 } 00085 00086 00087 /* 00088 * nFeatureFlags is typed to FT_ULong to accept that in 00089 * mort (typed FT_UShort) and morx (typed FT_ULong). 00090 */ 00091 FT_LOCAL_DEF( void ) 00092 gxv_mort_featurearray_validate( FT_Bytes table, 00093 FT_Bytes limit, 00094 FT_ULong nFeatureFlags, 00095 GXV_Validator valid ) 00096 { 00097 FT_Bytes p = table; 00098 FT_ULong i; 00099 00100 GXV_mort_featureRec f = GXV_MORT_FEATURE_OFF; 00101 00102 00103 GXV_NAME_ENTER( "mort feature list" ); 00104 for ( i = 0; i < nFeatureFlags; i++ ) 00105 { 00106 GXV_LIMIT_CHECK( 2 + 2 + 4 + 4 ); 00107 f.featureType = FT_NEXT_USHORT( p ); 00108 f.featureSetting = FT_NEXT_USHORT( p ); 00109 f.enableFlags = FT_NEXT_ULONG( p ); 00110 f.disableFlags = FT_NEXT_ULONG( p ); 00111 00112 gxv_mort_feature_validate( &f, valid ); 00113 } 00114 00115 if ( !IS_GXV_MORT_FEATURE_OFF( f ) ) 00116 FT_INVALID_DATA; 00117 00118 valid->subtable_length = p - table; 00119 GXV_EXIT; 00120 } 00121 00122 00123 FT_LOCAL_DEF( void ) 00124 gxv_mort_coverage_validate( FT_UShort coverage, 00125 GXV_Validator valid ) 00126 { 00127 FT_UNUSED( valid ); 00128 00129 if ( coverage & 0x8000U ) 00130 GXV_TRACE(( " this subtable is for vertical text only\n" )); 00131 else 00132 GXV_TRACE(( " this subtable is for horizontal text only\n" )); 00133 00134 if ( coverage & 0x4000 ) 00135 GXV_TRACE(( " this subtable is applied to glyph array " 00136 "in descending order\n" )); 00137 else 00138 GXV_TRACE(( " this subtable is applied to glyph array " 00139 "in ascending order\n" )); 00140 00141 if ( coverage & 0x2000 ) 00142 GXV_TRACE(( " this subtable is forcibly applied to " 00143 "vertical/horizontal text\n" )); 00144 00145 if ( coverage & 0x1FF8 ) 00146 GXV_TRACE(( " coverage has non-zero bits in reserved area\n" )); 00147 } 00148 00149 00150 static void 00151 gxv_mort_subtables_validate( FT_Bytes table, 00152 FT_Bytes limit, 00153 FT_UShort nSubtables, 00154 GXV_Validator valid ) 00155 { 00156 FT_Bytes p = table; 00157 00158 GXV_Validate_Func fmt_funcs_table[] = 00159 { 00160 gxv_mort_subtable_type0_validate, /* 0 */ 00161 gxv_mort_subtable_type1_validate, /* 1 */ 00162 gxv_mort_subtable_type2_validate, /* 2 */ 00163 NULL, /* 3 */ 00164 gxv_mort_subtable_type4_validate, /* 4 */ 00165 gxv_mort_subtable_type5_validate, /* 5 */ 00166 00167 }; 00168 00169 GXV_Validate_Func func; 00170 FT_UShort i; 00171 00172 00173 GXV_NAME_ENTER( "subtables in a chain" ); 00174 00175 for ( i = 0; i < nSubtables; i++ ) 00176 { 00177 FT_UShort length; 00178 FT_UShort coverage; 00179 FT_ULong subFeatureFlags; 00180 FT_UInt type; 00181 FT_UInt rest; 00182 00183 00184 GXV_LIMIT_CHECK( 2 + 2 + 4 ); 00185 length = FT_NEXT_USHORT( p ); 00186 coverage = FT_NEXT_USHORT( p ); 00187 subFeatureFlags = FT_NEXT_ULONG( p ); 00188 00189 GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", 00190 i + 1, nSubtables, length )); 00191 type = coverage & 0x0007; 00192 rest = length - ( 2 + 2 + 4 ); 00193 00194 GXV_LIMIT_CHECK( rest ); 00195 gxv_mort_coverage_validate( coverage, valid ); 00196 00197 if ( type > 5 ) 00198 FT_INVALID_FORMAT; 00199 00200 func = fmt_funcs_table[type]; 00201 if ( func == NULL ) 00202 GXV_TRACE(( "morx type %d is reserved\n", type )); 00203 00204 func( p, p + rest, valid ); 00205 00206 p += rest; 00207 } 00208 00209 valid->subtable_length = p - table; 00210 00211 GXV_EXIT; 00212 } 00213 00214 00215 static void 00216 gxv_mort_chain_validate( FT_Bytes table, 00217 FT_Bytes limit, 00218 GXV_Validator valid ) 00219 { 00220 FT_Bytes p = table; 00221 FT_ULong defaultFlags; 00222 FT_ULong chainLength; 00223 FT_UShort nFeatureFlags; 00224 FT_UShort nSubtables; 00225 00226 00227 GXV_NAME_ENTER( "mort chain header" ); 00228 00229 GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); 00230 defaultFlags = FT_NEXT_ULONG( p ); 00231 chainLength = FT_NEXT_ULONG( p ); 00232 nFeatureFlags = FT_NEXT_USHORT( p ); 00233 nSubtables = FT_NEXT_USHORT( p ); 00234 00235 gxv_mort_featurearray_validate( p, table + chainLength, 00236 nFeatureFlags, valid ); 00237 p += valid->subtable_length; 00238 gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); 00239 valid->subtable_length = chainLength; 00240 00241 GXV_EXIT; 00242 } 00243 00244 00245 FT_LOCAL_DEF( void ) 00246 gxv_mort_validate( FT_Bytes table, 00247 FT_Face face, 00248 FT_Validator ftvalid ) 00249 { 00250 GXV_ValidatorRec validrec; 00251 GXV_Validator valid = &validrec; 00252 FT_Bytes p = table; 00253 FT_Bytes limit = 0; 00254 FT_ULong version; 00255 FT_ULong nChains; 00256 FT_ULong i; 00257 00258 00259 valid->root = ftvalid; 00260 valid->face = face; 00261 limit = valid->root->limit; 00262 00263 FT_TRACE3(( "validating `mort' table\n" )); 00264 GXV_INIT; 00265 00266 GXV_LIMIT_CHECK( 4 + 4 ); 00267 version = FT_NEXT_ULONG( p ); 00268 nChains = FT_NEXT_ULONG( p ); 00269 00270 if (version != 0x00010000UL) 00271 FT_INVALID_FORMAT; 00272 00273 for ( i = 0; i < nChains; i++ ) 00274 { 00275 GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); 00276 GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); 00277 gxv_mort_chain_validate( p, limit, valid ); 00278 p += valid->subtable_length; 00279 } 00280 00281 FT_TRACE4(( "\n" )); 00282 } 00283 00284 00285 /* END */ Generated on Sat May 26 2012 04:32:44 for ReactOS by
1.7.6.1
|