Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenotvgsub.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* otvgsub.c */ 00004 /* */ 00005 /* OpenType GSUB table validation (body). */ 00006 /* */ 00007 /* Copyright 2004, 2005, 2007 by */ 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 #include "otvalid.h" 00020 #include "otvcommn.h" 00021 00022 00023 /*************************************************************************/ 00024 /* */ 00025 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00026 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00027 /* messages during execution. */ 00028 /* */ 00029 #undef FT_COMPONENT 00030 #define FT_COMPONENT trace_otvgsub 00031 00032 00033 /*************************************************************************/ 00034 /*************************************************************************/ 00035 /***** *****/ 00036 /***** GSUB LOOKUP TYPE 1 *****/ 00037 /***** *****/ 00038 /*************************************************************************/ 00039 /*************************************************************************/ 00040 00041 /* uses valid->glyph_count */ 00042 00043 static void 00044 otv_SingleSubst_validate( FT_Bytes table, 00045 OTV_Validator valid ) 00046 { 00047 FT_Bytes p = table; 00048 FT_UInt SubstFormat; 00049 00050 00051 OTV_NAME_ENTER( "SingleSubst" ); 00052 00053 OTV_LIMIT_CHECK( 2 ); 00054 SubstFormat = FT_NEXT_USHORT( p ); 00055 00056 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00057 00058 switch ( SubstFormat ) 00059 { 00060 case 1: /* SingleSubstFormat1 */ 00061 { 00062 FT_Bytes Coverage; 00063 FT_Int DeltaGlyphID; 00064 FT_Long idx; 00065 00066 00067 OTV_LIMIT_CHECK( 4 ); 00068 Coverage = table + FT_NEXT_USHORT( p ); 00069 DeltaGlyphID = FT_NEXT_SHORT( p ); 00070 00071 otv_Coverage_validate( Coverage, valid, -1 ); 00072 00073 idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID; 00074 if ( idx < 0 ) 00075 FT_INVALID_DATA; 00076 00077 idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID; 00078 if ( (FT_UInt)idx >= valid->glyph_count ) 00079 FT_INVALID_DATA; 00080 } 00081 break; 00082 00083 case 2: /* SingleSubstFormat2 */ 00084 { 00085 FT_UInt Coverage, GlyphCount; 00086 00087 00088 OTV_LIMIT_CHECK( 4 ); 00089 Coverage = FT_NEXT_USHORT( p ); 00090 GlyphCount = FT_NEXT_USHORT( p ); 00091 00092 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); 00093 00094 otv_Coverage_validate( table + Coverage, valid, GlyphCount ); 00095 00096 OTV_LIMIT_CHECK( GlyphCount * 2 ); 00097 00098 /* Substitute */ 00099 for ( ; GlyphCount > 0; GlyphCount-- ) 00100 if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) 00101 FT_INVALID_GLYPH_ID; 00102 } 00103 break; 00104 00105 default: 00106 FT_INVALID_FORMAT; 00107 } 00108 00109 OTV_EXIT; 00110 } 00111 00112 00113 /*************************************************************************/ 00114 /*************************************************************************/ 00115 /***** *****/ 00116 /***** GSUB LOOKUP TYPE 2 *****/ 00117 /***** *****/ 00118 /*************************************************************************/ 00119 /*************************************************************************/ 00120 00121 /* sets valid->extra1 (glyph count) */ 00122 00123 static void 00124 otv_MultipleSubst_validate( FT_Bytes table, 00125 OTV_Validator valid ) 00126 { 00127 FT_Bytes p = table; 00128 FT_UInt SubstFormat; 00129 00130 00131 OTV_NAME_ENTER( "MultipleSubst" ); 00132 00133 OTV_LIMIT_CHECK( 2 ); 00134 SubstFormat = FT_NEXT_USHORT( p ); 00135 00136 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00137 00138 switch ( SubstFormat ) 00139 { 00140 case 1: 00141 valid->extra1 = valid->glyph_count; 00142 OTV_NEST2( MultipleSubstFormat1, Sequence ); 00143 OTV_RUN( table, valid ); 00144 break; 00145 00146 default: 00147 FT_INVALID_FORMAT; 00148 } 00149 00150 OTV_EXIT; 00151 } 00152 00153 00154 /*************************************************************************/ 00155 /*************************************************************************/ 00156 /***** *****/ 00157 /***** GSUB LOOKUP TYPE 3 *****/ 00158 /***** *****/ 00159 /*************************************************************************/ 00160 /*************************************************************************/ 00161 00162 /* sets valid->extra1 (glyph count) */ 00163 00164 static void 00165 otv_AlternateSubst_validate( FT_Bytes table, 00166 OTV_Validator valid ) 00167 { 00168 FT_Bytes p = table; 00169 FT_UInt SubstFormat; 00170 00171 00172 OTV_NAME_ENTER( "AlternateSubst" ); 00173 00174 OTV_LIMIT_CHECK( 2 ); 00175 SubstFormat = FT_NEXT_USHORT( p ); 00176 00177 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00178 00179 switch ( SubstFormat ) 00180 { 00181 case 1: 00182 valid->extra1 = valid->glyph_count; 00183 OTV_NEST2( AlternateSubstFormat1, AlternateSet ); 00184 OTV_RUN( table, valid ); 00185 break; 00186 00187 default: 00188 FT_INVALID_FORMAT; 00189 } 00190 00191 OTV_EXIT; 00192 } 00193 00194 00195 /*************************************************************************/ 00196 /*************************************************************************/ 00197 /***** *****/ 00198 /***** GSUB LOOKUP TYPE 4 *****/ 00199 /***** *****/ 00200 /*************************************************************************/ 00201 /*************************************************************************/ 00202 00203 #define LigatureFunc otv_Ligature_validate 00204 00205 /* uses valid->glyph_count */ 00206 00207 static void 00208 otv_Ligature_validate( FT_Bytes table, 00209 OTV_Validator valid ) 00210 { 00211 FT_Bytes p = table; 00212 FT_UInt LigatureGlyph, CompCount; 00213 00214 00215 OTV_ENTER; 00216 00217 OTV_LIMIT_CHECK( 4 ); 00218 LigatureGlyph = FT_NEXT_USHORT( p ); 00219 if ( LigatureGlyph >= valid->glyph_count ) 00220 FT_INVALID_DATA; 00221 00222 CompCount = FT_NEXT_USHORT( p ); 00223 00224 OTV_TRACE(( " (CompCount = %d)\n", CompCount )); 00225 00226 if ( CompCount == 0 ) 00227 FT_INVALID_DATA; 00228 00229 CompCount--; 00230 00231 OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */ 00232 00233 /* no need to check the Component glyph indices */ 00234 00235 OTV_EXIT; 00236 } 00237 00238 00239 static void 00240 otv_LigatureSubst_validate( FT_Bytes table, 00241 OTV_Validator valid ) 00242 { 00243 FT_Bytes p = table; 00244 FT_UInt SubstFormat; 00245 00246 00247 OTV_NAME_ENTER( "LigatureSubst" ); 00248 00249 OTV_LIMIT_CHECK( 2 ); 00250 SubstFormat = FT_NEXT_USHORT( p ); 00251 00252 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00253 00254 switch ( SubstFormat ) 00255 { 00256 case 1: 00257 OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); 00258 OTV_RUN( table, valid ); 00259 break; 00260 00261 default: 00262 FT_INVALID_FORMAT; 00263 } 00264 00265 OTV_EXIT; 00266 } 00267 00268 00269 /*************************************************************************/ 00270 /*************************************************************************/ 00271 /***** *****/ 00272 /***** GSUB LOOKUP TYPE 5 *****/ 00273 /***** *****/ 00274 /*************************************************************************/ 00275 /*************************************************************************/ 00276 00277 /* sets valid->extra1 (lookup count) */ 00278 00279 static void 00280 otv_ContextSubst_validate( FT_Bytes table, 00281 OTV_Validator valid ) 00282 { 00283 FT_Bytes p = table; 00284 FT_UInt SubstFormat; 00285 00286 00287 OTV_NAME_ENTER( "ContextSubst" ); 00288 00289 OTV_LIMIT_CHECK( 2 ); 00290 SubstFormat = FT_NEXT_USHORT( p ); 00291 00292 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00293 00294 switch ( SubstFormat ) 00295 { 00296 case 1: 00297 /* no need to check glyph indices/classes used as input for these */ 00298 /* context rules since even invalid glyph indices/classes return */ 00299 /* meaningful results */ 00300 00301 valid->extra1 = valid->lookup_count; 00302 OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule ); 00303 OTV_RUN( table, valid ); 00304 break; 00305 00306 case 2: 00307 /* no need to check glyph indices/classes used as input for these */ 00308 /* context rules since even invalid glyph indices/classes return */ 00309 /* meaningful results */ 00310 00311 OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule ); 00312 OTV_RUN( table, valid ); 00313 break; 00314 00315 case 3: 00316 OTV_NEST1( ContextSubstFormat3 ); 00317 OTV_RUN( table, valid ); 00318 break; 00319 00320 default: 00321 FT_INVALID_FORMAT; 00322 } 00323 00324 OTV_EXIT; 00325 } 00326 00327 00328 /*************************************************************************/ 00329 /*************************************************************************/ 00330 /***** *****/ 00331 /***** GSUB LOOKUP TYPE 6 *****/ 00332 /***** *****/ 00333 /*************************************************************************/ 00334 /*************************************************************************/ 00335 00336 /* sets valid->extra1 (lookup count) */ 00337 00338 static void 00339 otv_ChainContextSubst_validate( FT_Bytes table, 00340 OTV_Validator valid ) 00341 { 00342 FT_Bytes p = table; 00343 FT_UInt SubstFormat; 00344 00345 00346 OTV_NAME_ENTER( "ChainContextSubst" ); 00347 00348 OTV_LIMIT_CHECK( 2 ); 00349 SubstFormat = FT_NEXT_USHORT( p ); 00350 00351 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00352 00353 switch ( SubstFormat ) 00354 { 00355 case 1: 00356 /* no need to check glyph indices/classes used as input for these */ 00357 /* context rules since even invalid glyph indices/classes return */ 00358 /* meaningful results */ 00359 00360 valid->extra1 = valid->lookup_count; 00361 OTV_NEST3( ChainContextSubstFormat1, 00362 ChainSubRuleSet, ChainSubRule ); 00363 OTV_RUN( table, valid ); 00364 break; 00365 00366 case 2: 00367 /* no need to check glyph indices/classes used as input for these */ 00368 /* context rules since even invalid glyph indices/classes return */ 00369 /* meaningful results */ 00370 00371 OTV_NEST3( ChainContextSubstFormat2, 00372 ChainSubClassSet, ChainSubClassRule ); 00373 OTV_RUN( table, valid ); 00374 break; 00375 00376 case 3: 00377 OTV_NEST1( ChainContextSubstFormat3 ); 00378 OTV_RUN( table, valid ); 00379 break; 00380 00381 default: 00382 FT_INVALID_FORMAT; 00383 } 00384 00385 OTV_EXIT; 00386 } 00387 00388 00389 /*************************************************************************/ 00390 /*************************************************************************/ 00391 /***** *****/ 00392 /***** GSUB LOOKUP TYPE 7 *****/ 00393 /***** *****/ 00394 /*************************************************************************/ 00395 /*************************************************************************/ 00396 00397 /* uses valid->type_funcs */ 00398 00399 static void 00400 otv_ExtensionSubst_validate( FT_Bytes table, 00401 OTV_Validator valid ) 00402 { 00403 FT_Bytes p = table; 00404 FT_UInt SubstFormat; 00405 00406 00407 OTV_NAME_ENTER( "ExtensionSubst" ); 00408 00409 OTV_LIMIT_CHECK( 2 ); 00410 SubstFormat = FT_NEXT_USHORT( p ); 00411 00412 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00413 00414 switch ( SubstFormat ) 00415 { 00416 case 1: /* ExtensionSubstFormat1 */ 00417 { 00418 FT_UInt ExtensionLookupType; 00419 FT_ULong ExtensionOffset; 00420 OTV_Validate_Func validate; 00421 00422 00423 OTV_LIMIT_CHECK( 6 ); 00424 ExtensionLookupType = FT_NEXT_USHORT( p ); 00425 ExtensionOffset = FT_NEXT_ULONG( p ); 00426 00427 if ( ExtensionLookupType == 0 || 00428 ExtensionLookupType == 7 || 00429 ExtensionLookupType > 8 ) 00430 FT_INVALID_DATA; 00431 00432 validate = valid->type_funcs[ExtensionLookupType - 1]; 00433 validate( table + ExtensionOffset, valid ); 00434 } 00435 break; 00436 00437 default: 00438 FT_INVALID_FORMAT; 00439 } 00440 00441 OTV_EXIT; 00442 } 00443 00444 00445 /*************************************************************************/ 00446 /*************************************************************************/ 00447 /***** *****/ 00448 /***** GSUB LOOKUP TYPE 8 *****/ 00449 /***** *****/ 00450 /*************************************************************************/ 00451 /*************************************************************************/ 00452 00453 /* uses valid->glyph_count */ 00454 00455 static void 00456 otv_ReverseChainSingleSubst_validate( FT_Bytes table, 00457 OTV_Validator valid ) 00458 { 00459 FT_Bytes p = table, Coverage; 00460 FT_UInt SubstFormat; 00461 FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount; 00462 00463 00464 OTV_NAME_ENTER( "ReverseChainSingleSubst" ); 00465 00466 OTV_LIMIT_CHECK( 2 ); 00467 SubstFormat = FT_NEXT_USHORT( p ); 00468 00469 OTV_TRACE(( " (format %d)\n", SubstFormat )); 00470 00471 switch ( SubstFormat ) 00472 { 00473 case 1: /* ReverseChainSingleSubstFormat1 */ 00474 OTV_LIMIT_CHECK( 4 ); 00475 Coverage = table + FT_NEXT_USHORT( p ); 00476 BacktrackGlyphCount = FT_NEXT_USHORT( p ); 00477 00478 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); 00479 00480 otv_Coverage_validate( Coverage, valid, -1 ); 00481 00482 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); 00483 00484 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) 00485 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); 00486 00487 LookaheadGlyphCount = FT_NEXT_USHORT( p ); 00488 00489 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); 00490 00491 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); 00492 00493 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) 00494 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 ); 00495 00496 GlyphCount = FT_NEXT_USHORT( p ); 00497 00498 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); 00499 00500 if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) 00501 FT_INVALID_DATA; 00502 00503 OTV_LIMIT_CHECK( GlyphCount * 2 ); 00504 00505 /* Substitute */ 00506 for ( ; GlyphCount > 0; GlyphCount-- ) 00507 if ( FT_NEXT_USHORT( p ) >= valid->glyph_count ) 00508 FT_INVALID_DATA; 00509 00510 break; 00511 00512 default: 00513 FT_INVALID_FORMAT; 00514 } 00515 00516 OTV_EXIT; 00517 } 00518 00519 00520 static const OTV_Validate_Func otv_gsub_validate_funcs[8] = 00521 { 00522 otv_SingleSubst_validate, 00523 otv_MultipleSubst_validate, 00524 otv_AlternateSubst_validate, 00525 otv_LigatureSubst_validate, 00526 otv_ContextSubst_validate, 00527 otv_ChainContextSubst_validate, 00528 otv_ExtensionSubst_validate, 00529 otv_ReverseChainSingleSubst_validate 00530 }; 00531 00532 00533 /*************************************************************************/ 00534 /*************************************************************************/ 00535 /***** *****/ 00536 /***** GSUB TABLE *****/ 00537 /***** *****/ 00538 /*************************************************************************/ 00539 /*************************************************************************/ 00540 00541 /* sets valid->type_count */ 00542 /* sets valid->type_funcs */ 00543 /* sets valid->glyph_count */ 00544 00545 FT_LOCAL_DEF( void ) 00546 otv_GSUB_validate( FT_Bytes table, 00547 FT_UInt glyph_count, 00548 FT_Validator ftvalid ) 00549 { 00550 OTV_ValidatorRec validrec; 00551 OTV_Validator valid = &validrec; 00552 FT_Bytes p = table; 00553 FT_UInt ScriptList, FeatureList, LookupList; 00554 00555 00556 valid->root = ftvalid; 00557 00558 FT_TRACE3(( "validating GSUB table\n" )); 00559 OTV_INIT; 00560 00561 OTV_LIMIT_CHECK( 10 ); 00562 00563 if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ 00564 FT_INVALID_FORMAT; 00565 00566 ScriptList = FT_NEXT_USHORT( p ); 00567 FeatureList = FT_NEXT_USHORT( p ); 00568 LookupList = FT_NEXT_USHORT( p ); 00569 00570 valid->type_count = 8; 00571 valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs; 00572 valid->glyph_count = glyph_count; 00573 00574 otv_LookupList_validate( table + LookupList, 00575 valid ); 00576 otv_FeatureList_validate( table + FeatureList, table + LookupList, 00577 valid ); 00578 otv_ScriptList_validate( table + ScriptList, table + FeatureList, 00579 valid ); 00580 00581 FT_TRACE4(( "\n" )); 00582 } 00583 00584 00585 /* END */ Generated on Fri May 25 2012 04:32:22 for ReactOS by
1.7.6.1
|