Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenotvgpos.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* otvgpos.c */ 00004 /* */ 00005 /* OpenType GPOS table validation (body). */ 00006 /* */ 00007 /* Copyright 2002, 2004, 2005, 2006, 2007, 2008 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 #include "otvgpos.h" 00022 00023 00024 /*************************************************************************/ 00025 /* */ 00026 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00027 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00028 /* messages during execution. */ 00029 /* */ 00030 #undef FT_COMPONENT 00031 #define FT_COMPONENT trace_otvgpos 00032 00033 00034 static void 00035 otv_Anchor_validate( FT_Bytes table, 00036 OTV_Validator valid ); 00037 00038 static void 00039 otv_MarkArray_validate( FT_Bytes table, 00040 OTV_Validator valid ); 00041 00042 00043 /*************************************************************************/ 00044 /*************************************************************************/ 00045 /***** *****/ 00046 /***** UTILITY FUNCTIONS *****/ 00047 /***** *****/ 00048 /*************************************************************************/ 00049 /*************************************************************************/ 00050 00051 #define BaseArrayFunc otv_x_sxy 00052 #define LigatureAttachFunc otv_x_sxy 00053 #define Mark2ArrayFunc otv_x_sxy 00054 00055 /* uses valid->extra1 (counter) */ 00056 /* uses valid->extra2 (boolean to handle NULL anchor field) */ 00057 00058 static void 00059 otv_x_sxy( FT_Bytes table, 00060 OTV_Validator valid ) 00061 { 00062 FT_Bytes p = table; 00063 FT_UInt Count, count1, table_size; 00064 00065 00066 OTV_ENTER; 00067 00068 OTV_LIMIT_CHECK( 2 ); 00069 00070 Count = FT_NEXT_USHORT( p ); 00071 00072 OTV_TRACE(( " (Count = %d)\n", Count )); 00073 00074 OTV_LIMIT_CHECK( Count * valid->extra1 * 2 ); 00075 00076 table_size = Count * valid->extra1 * 2 + 2; 00077 00078 for ( ; Count > 0; Count-- ) 00079 for ( count1 = valid->extra1; count1 > 0; count1-- ) 00080 { 00081 OTV_OPTIONAL_TABLE( anchor_offset ); 00082 00083 00084 OTV_OPTIONAL_OFFSET( anchor_offset ); 00085 00086 if ( valid->extra2 ) 00087 { 00088 OTV_SIZE_CHECK( anchor_offset ); 00089 if ( anchor_offset ) 00090 otv_Anchor_validate( table + anchor_offset, valid ); 00091 } 00092 else 00093 otv_Anchor_validate( table + anchor_offset, valid ); 00094 } 00095 00096 OTV_EXIT; 00097 } 00098 00099 00100 #define MarkBasePosFormat1Func otv_u_O_O_u_O_O 00101 #define MarkLigPosFormat1Func otv_u_O_O_u_O_O 00102 #define MarkMarkPosFormat1Func otv_u_O_O_u_O_O 00103 00104 /* sets valid->extra1 (class count) */ 00105 00106 static void 00107 otv_u_O_O_u_O_O( FT_Bytes table, 00108 OTV_Validator valid ) 00109 { 00110 FT_Bytes p = table; 00111 FT_UInt Coverage1, Coverage2, ClassCount; 00112 FT_UInt Array1, Array2; 00113 OTV_Validate_Func func; 00114 00115 00116 OTV_ENTER; 00117 00118 p += 2; /* skip PosFormat */ 00119 00120 OTV_LIMIT_CHECK( 10 ); 00121 Coverage1 = FT_NEXT_USHORT( p ); 00122 Coverage2 = FT_NEXT_USHORT( p ); 00123 ClassCount = FT_NEXT_USHORT( p ); 00124 Array1 = FT_NEXT_USHORT( p ); 00125 Array2 = FT_NEXT_USHORT( p ); 00126 00127 otv_Coverage_validate( table + Coverage1, valid, -1 ); 00128 otv_Coverage_validate( table + Coverage2, valid, -1 ); 00129 00130 otv_MarkArray_validate( table + Array1, valid ); 00131 00132 valid->nesting_level++; 00133 func = valid->func[valid->nesting_level]; 00134 valid->extra1 = ClassCount; 00135 00136 func( table + Array2, valid ); 00137 00138 valid->nesting_level--; 00139 00140 OTV_EXIT; 00141 } 00142 00143 00144 /*************************************************************************/ 00145 /*************************************************************************/ 00146 /***** *****/ 00147 /***** VALUE RECORDS *****/ 00148 /***** *****/ 00149 /*************************************************************************/ 00150 /*************************************************************************/ 00151 00152 static FT_UInt 00153 otv_value_length( FT_UInt format ) 00154 { 00155 FT_UInt count; 00156 00157 00158 count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 ); 00159 count = ( ( count & 0xCC ) >> 2 ) + ( count & 0x33 ); 00160 count = ( ( count & 0xF0 ) >> 4 ) + ( count & 0x0F ); 00161 00162 return count * 2; 00163 } 00164 00165 00166 /* uses valid->extra3 (pointer to base table) */ 00167 00168 static void 00169 otv_ValueRecord_validate( FT_Bytes table, 00170 FT_UInt format, 00171 OTV_Validator valid ) 00172 { 00173 FT_Bytes p = table; 00174 FT_UInt count; 00175 00176 #ifdef FT_DEBUG_LEVEL_TRACE 00177 FT_Int loop; 00178 FT_ULong res = 0; 00179 00180 00181 OTV_NAME_ENTER( "ValueRecord" ); 00182 00183 /* display `format' in dual representation */ 00184 for ( loop = 7; loop >= 0; loop-- ) 00185 { 00186 res <<= 4; 00187 res += ( format >> loop ) & 1; 00188 } 00189 00190 OTV_TRACE(( " (format 0b%08lx)\n", res )); 00191 #endif 00192 00193 if ( format >= 0x100 ) 00194 FT_INVALID_FORMAT; 00195 00196 for ( count = 4; count > 0; count-- ) 00197 { 00198 if ( format & 1 ) 00199 { 00200 /* XPlacement, YPlacement, XAdvance, YAdvance */ 00201 OTV_LIMIT_CHECK( 2 ); 00202 p += 2; 00203 } 00204 00205 format >>= 1; 00206 } 00207 00208 for ( count = 4; count > 0; count-- ) 00209 { 00210 if ( format & 1 ) 00211 { 00212 FT_PtrDist table_size; 00213 00214 OTV_OPTIONAL_TABLE( device ); 00215 00216 00217 /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */ 00218 OTV_LIMIT_CHECK( 2 ); 00219 OTV_OPTIONAL_OFFSET( device ); 00220 00221 /* XXX: this value is usually too small, especially if the current */ 00222 /* ValueRecord is part of an array -- getting the correct table */ 00223 /* size is probably not worth the trouble */ 00224 00225 table_size = p - valid->extra3; 00226 00227 OTV_SIZE_CHECK( device ); 00228 if ( device ) 00229 otv_Device_validate( valid->extra3 + device, valid ); 00230 } 00231 format >>= 1; 00232 } 00233 00234 OTV_EXIT; 00235 } 00236 00237 00238 /*************************************************************************/ 00239 /*************************************************************************/ 00240 /***** *****/ 00241 /***** ANCHORS *****/ 00242 /***** *****/ 00243 /*************************************************************************/ 00244 /*************************************************************************/ 00245 00246 static void 00247 otv_Anchor_validate( FT_Bytes table, 00248 OTV_Validator valid ) 00249 { 00250 FT_Bytes p = table; 00251 FT_UInt AnchorFormat; 00252 00253 00254 OTV_NAME_ENTER( "Anchor"); 00255 00256 OTV_LIMIT_CHECK( 6 ); 00257 AnchorFormat = FT_NEXT_USHORT( p ); 00258 00259 OTV_TRACE(( " (format %d)\n", AnchorFormat )); 00260 00261 p += 4; /* skip XCoordinate and YCoordinate */ 00262 00263 switch ( AnchorFormat ) 00264 { 00265 case 1: 00266 break; 00267 00268 case 2: 00269 OTV_LIMIT_CHECK( 2 ); /* AnchorPoint */ 00270 break; 00271 00272 case 3: 00273 { 00274 FT_UInt table_size; 00275 00276 OTV_OPTIONAL_TABLE( XDeviceTable ); 00277 OTV_OPTIONAL_TABLE( YDeviceTable ); 00278 00279 00280 OTV_LIMIT_CHECK( 4 ); 00281 OTV_OPTIONAL_OFFSET( XDeviceTable ); 00282 OTV_OPTIONAL_OFFSET( YDeviceTable ); 00283 00284 table_size = 6 + 4; 00285 00286 OTV_SIZE_CHECK( XDeviceTable ); 00287 if ( XDeviceTable ) 00288 otv_Device_validate( table + XDeviceTable, valid ); 00289 00290 OTV_SIZE_CHECK( YDeviceTable ); 00291 if ( YDeviceTable ) 00292 otv_Device_validate( table + YDeviceTable, valid ); 00293 } 00294 break; 00295 00296 default: 00297 FT_INVALID_FORMAT; 00298 } 00299 00300 OTV_EXIT; 00301 } 00302 00303 00304 /*************************************************************************/ 00305 /*************************************************************************/ 00306 /***** *****/ 00307 /***** MARK ARRAYS *****/ 00308 /***** *****/ 00309 /*************************************************************************/ 00310 /*************************************************************************/ 00311 00312 static void 00313 otv_MarkArray_validate( FT_Bytes table, 00314 OTV_Validator valid ) 00315 { 00316 FT_Bytes p = table; 00317 FT_UInt MarkCount; 00318 00319 00320 OTV_NAME_ENTER( "MarkArray" ); 00321 00322 OTV_LIMIT_CHECK( 2 ); 00323 MarkCount = FT_NEXT_USHORT( p ); 00324 00325 OTV_TRACE(( " (MarkCount = %d)\n", MarkCount )); 00326 00327 OTV_LIMIT_CHECK( MarkCount * 4 ); 00328 00329 /* MarkRecord */ 00330 for ( ; MarkCount > 0; MarkCount-- ) 00331 { 00332 p += 2; /* skip Class */ 00333 /* MarkAnchor */ 00334 otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid ); 00335 } 00336 00337 OTV_EXIT; 00338 } 00339 00340 00341 /*************************************************************************/ 00342 /*************************************************************************/ 00343 /***** *****/ 00344 /***** GPOS LOOKUP TYPE 1 *****/ 00345 /***** *****/ 00346 /*************************************************************************/ 00347 /*************************************************************************/ 00348 00349 /* sets valid->extra3 (pointer to base table) */ 00350 00351 static void 00352 otv_SinglePos_validate( FT_Bytes table, 00353 OTV_Validator valid ) 00354 { 00355 FT_Bytes p = table; 00356 FT_UInt PosFormat; 00357 00358 00359 OTV_NAME_ENTER( "SinglePos" ); 00360 00361 OTV_LIMIT_CHECK( 2 ); 00362 PosFormat = FT_NEXT_USHORT( p ); 00363 00364 OTV_TRACE(( " (format %d)\n", PosFormat )); 00365 00366 valid->extra3 = table; 00367 00368 switch ( PosFormat ) 00369 { 00370 case 1: /* SinglePosFormat1 */ 00371 { 00372 FT_UInt Coverage, ValueFormat; 00373 00374 00375 OTV_LIMIT_CHECK( 4 ); 00376 Coverage = FT_NEXT_USHORT( p ); 00377 ValueFormat = FT_NEXT_USHORT( p ); 00378 00379 otv_Coverage_validate( table + Coverage, valid, -1 ); 00380 otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */ 00381 } 00382 break; 00383 00384 case 2: /* SinglePosFormat2 */ 00385 { 00386 FT_UInt Coverage, ValueFormat, ValueCount, len_value; 00387 00388 00389 OTV_LIMIT_CHECK( 6 ); 00390 Coverage = FT_NEXT_USHORT( p ); 00391 ValueFormat = FT_NEXT_USHORT( p ); 00392 ValueCount = FT_NEXT_USHORT( p ); 00393 00394 OTV_TRACE(( " (ValueCount = %d)\n", ValueCount )); 00395 00396 len_value = otv_value_length( ValueFormat ); 00397 00398 otv_Coverage_validate( table + Coverage, valid, ValueCount ); 00399 00400 OTV_LIMIT_CHECK( ValueCount * len_value ); 00401 00402 /* Value */ 00403 for ( ; ValueCount > 0; ValueCount-- ) 00404 { 00405 otv_ValueRecord_validate( p, ValueFormat, valid ); 00406 p += len_value; 00407 } 00408 } 00409 break; 00410 00411 default: 00412 FT_INVALID_FORMAT; 00413 } 00414 00415 OTV_EXIT; 00416 } 00417 00418 00419 /*************************************************************************/ 00420 /*************************************************************************/ 00421 /***** *****/ 00422 /***** GPOS LOOKUP TYPE 2 *****/ 00423 /***** *****/ 00424 /*************************************************************************/ 00425 /*************************************************************************/ 00426 00427 static void 00428 otv_PairSet_validate( FT_Bytes table, 00429 FT_UInt format1, 00430 FT_UInt format2, 00431 OTV_Validator valid ) 00432 { 00433 FT_Bytes p = table; 00434 FT_UInt value_len1, value_len2, PairValueCount; 00435 00436 00437 OTV_NAME_ENTER( "PairSet" ); 00438 00439 OTV_LIMIT_CHECK( 2 ); 00440 PairValueCount = FT_NEXT_USHORT( p ); 00441 00442 OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount )); 00443 00444 value_len1 = otv_value_length( format1 ); 00445 value_len2 = otv_value_length( format2 ); 00446 00447 OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) ); 00448 00449 /* PairValueRecord */ 00450 for ( ; PairValueCount > 0; PairValueCount-- ) 00451 { 00452 p += 2; /* skip SecondGlyph */ 00453 00454 if ( format1 ) 00455 otv_ValueRecord_validate( p, format1, valid ); /* Value1 */ 00456 p += value_len1; 00457 00458 if ( format2 ) 00459 otv_ValueRecord_validate( p, format2, valid ); /* Value2 */ 00460 p += value_len2; 00461 } 00462 00463 OTV_EXIT; 00464 } 00465 00466 00467 /* sets valid->extra3 (pointer to base table) */ 00468 00469 static void 00470 otv_PairPos_validate( FT_Bytes table, 00471 OTV_Validator valid ) 00472 { 00473 FT_Bytes p = table; 00474 FT_UInt PosFormat; 00475 00476 00477 OTV_NAME_ENTER( "PairPos" ); 00478 00479 OTV_LIMIT_CHECK( 2 ); 00480 PosFormat = FT_NEXT_USHORT( p ); 00481 00482 OTV_TRACE(( " (format %d)\n", PosFormat )); 00483 00484 valid->extra3 = table; 00485 00486 switch ( PosFormat ) 00487 { 00488 case 1: /* PairPosFormat1 */ 00489 { 00490 FT_UInt Coverage, ValueFormat1, ValueFormat2, PairSetCount; 00491 00492 00493 OTV_LIMIT_CHECK( 8 ); 00494 Coverage = FT_NEXT_USHORT( p ); 00495 ValueFormat1 = FT_NEXT_USHORT( p ); 00496 ValueFormat2 = FT_NEXT_USHORT( p ); 00497 PairSetCount = FT_NEXT_USHORT( p ); 00498 00499 OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount )); 00500 00501 otv_Coverage_validate( table + Coverage, valid, -1 ); 00502 00503 OTV_LIMIT_CHECK( PairSetCount * 2 ); 00504 00505 /* PairSetOffset */ 00506 for ( ; PairSetCount > 0; PairSetCount-- ) 00507 otv_PairSet_validate( table + FT_NEXT_USHORT( p ), 00508 ValueFormat1, ValueFormat2, valid ); 00509 } 00510 break; 00511 00512 case 2: /* PairPosFormat2 */ 00513 { 00514 FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2; 00515 FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count; 00516 00517 00518 OTV_LIMIT_CHECK( 14 ); 00519 Coverage = FT_NEXT_USHORT( p ); 00520 ValueFormat1 = FT_NEXT_USHORT( p ); 00521 ValueFormat2 = FT_NEXT_USHORT( p ); 00522 ClassDef1 = FT_NEXT_USHORT( p ); 00523 ClassDef2 = FT_NEXT_USHORT( p ); 00524 ClassCount1 = FT_NEXT_USHORT( p ); 00525 ClassCount2 = FT_NEXT_USHORT( p ); 00526 00527 OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 )); 00528 OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 )); 00529 00530 len_value1 = otv_value_length( ValueFormat1 ); 00531 len_value2 = otv_value_length( ValueFormat2 ); 00532 00533 otv_Coverage_validate( table + Coverage, valid, -1 ); 00534 otv_ClassDef_validate( table + ClassDef1, valid ); 00535 otv_ClassDef_validate( table + ClassDef2, valid ); 00536 00537 OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * 00538 ( len_value1 + len_value2 ) ); 00539 00540 /* Class1Record */ 00541 for ( ; ClassCount1 > 0; ClassCount1-- ) 00542 { 00543 /* Class2Record */ 00544 for ( count = ClassCount2; count > 0; count-- ) 00545 { 00546 if ( ValueFormat1 ) 00547 /* Value1 */ 00548 otv_ValueRecord_validate( p, ValueFormat1, valid ); 00549 p += len_value1; 00550 00551 if ( ValueFormat2 ) 00552 /* Value2 */ 00553 otv_ValueRecord_validate( p, ValueFormat2, valid ); 00554 p += len_value2; 00555 } 00556 } 00557 } 00558 break; 00559 00560 default: 00561 FT_INVALID_FORMAT; 00562 } 00563 00564 OTV_EXIT; 00565 } 00566 00567 00568 /*************************************************************************/ 00569 /*************************************************************************/ 00570 /***** *****/ 00571 /***** GPOS LOOKUP TYPE 3 *****/ 00572 /***** *****/ 00573 /*************************************************************************/ 00574 /*************************************************************************/ 00575 00576 static void 00577 otv_CursivePos_validate( FT_Bytes table, 00578 OTV_Validator valid ) 00579 { 00580 FT_Bytes p = table; 00581 FT_UInt PosFormat; 00582 00583 00584 OTV_NAME_ENTER( "CursivePos" ); 00585 00586 OTV_LIMIT_CHECK( 2 ); 00587 PosFormat = FT_NEXT_USHORT( p ); 00588 00589 OTV_TRACE(( " (format %d)\n", PosFormat )); 00590 00591 switch ( PosFormat ) 00592 { 00593 case 1: /* CursivePosFormat1 */ 00594 { 00595 FT_UInt table_size; 00596 FT_UInt Coverage, EntryExitCount; 00597 00598 OTV_OPTIONAL_TABLE( EntryAnchor ); 00599 OTV_OPTIONAL_TABLE( ExitAnchor ); 00600 00601 00602 OTV_LIMIT_CHECK( 4 ); 00603 Coverage = FT_NEXT_USHORT( p ); 00604 EntryExitCount = FT_NEXT_USHORT( p ); 00605 00606 OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount )); 00607 00608 otv_Coverage_validate( table + Coverage, valid, EntryExitCount ); 00609 00610 OTV_LIMIT_CHECK( EntryExitCount * 4 ); 00611 00612 table_size = EntryExitCount * 4 + 4; 00613 00614 /* EntryExitRecord */ 00615 for ( ; EntryExitCount > 0; EntryExitCount-- ) 00616 { 00617 OTV_OPTIONAL_OFFSET( EntryAnchor ); 00618 OTV_OPTIONAL_OFFSET( ExitAnchor ); 00619 00620 OTV_SIZE_CHECK( EntryAnchor ); 00621 if ( EntryAnchor ) 00622 otv_Anchor_validate( table + EntryAnchor, valid ); 00623 00624 OTV_SIZE_CHECK( ExitAnchor ); 00625 if ( ExitAnchor ) 00626 otv_Anchor_validate( table + ExitAnchor, valid ); 00627 } 00628 } 00629 break; 00630 00631 default: 00632 FT_INVALID_FORMAT; 00633 } 00634 00635 OTV_EXIT; 00636 } 00637 00638 00639 /*************************************************************************/ 00640 /*************************************************************************/ 00641 /***** *****/ 00642 /***** GPOS LOOKUP TYPE 4 *****/ 00643 /***** *****/ 00644 /*************************************************************************/ 00645 /*************************************************************************/ 00646 00647 /* UNDOCUMENTED (in OpenType 1.5): */ 00648 /* BaseRecord tables can contain NULL pointers. */ 00649 00650 /* sets valid->extra2 (1) */ 00651 00652 static void 00653 otv_MarkBasePos_validate( FT_Bytes table, 00654 OTV_Validator valid ) 00655 { 00656 FT_Bytes p = table; 00657 FT_UInt PosFormat; 00658 00659 00660 OTV_NAME_ENTER( "MarkBasePos" ); 00661 00662 OTV_LIMIT_CHECK( 2 ); 00663 PosFormat = FT_NEXT_USHORT( p ); 00664 00665 OTV_TRACE(( " (format %d)\n", PosFormat )); 00666 00667 switch ( PosFormat ) 00668 { 00669 case 1: 00670 valid->extra2 = 1; 00671 OTV_NEST2( MarkBasePosFormat1, BaseArray ); 00672 OTV_RUN( table, valid ); 00673 break; 00674 00675 default: 00676 FT_INVALID_FORMAT; 00677 } 00678 00679 OTV_EXIT; 00680 } 00681 00682 00683 /*************************************************************************/ 00684 /*************************************************************************/ 00685 /***** *****/ 00686 /***** GPOS LOOKUP TYPE 5 *****/ 00687 /***** *****/ 00688 /*************************************************************************/ 00689 /*************************************************************************/ 00690 00691 /* sets valid->extra2 (1) */ 00692 00693 static void 00694 otv_MarkLigPos_validate( FT_Bytes table, 00695 OTV_Validator valid ) 00696 { 00697 FT_Bytes p = table; 00698 FT_UInt PosFormat; 00699 00700 00701 OTV_NAME_ENTER( "MarkLigPos" ); 00702 00703 OTV_LIMIT_CHECK( 2 ); 00704 PosFormat = FT_NEXT_USHORT( p ); 00705 00706 OTV_TRACE(( " (format %d)\n", PosFormat )); 00707 00708 switch ( PosFormat ) 00709 { 00710 case 1: 00711 valid->extra2 = 1; 00712 OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach ); 00713 OTV_RUN( table, valid ); 00714 break; 00715 00716 default: 00717 FT_INVALID_FORMAT; 00718 } 00719 00720 OTV_EXIT; 00721 } 00722 00723 00724 /*************************************************************************/ 00725 /*************************************************************************/ 00726 /***** *****/ 00727 /***** GPOS LOOKUP TYPE 6 *****/ 00728 /***** *****/ 00729 /*************************************************************************/ 00730 /*************************************************************************/ 00731 00732 /* sets valid->extra2 (0) */ 00733 00734 static void 00735 otv_MarkMarkPos_validate( FT_Bytes table, 00736 OTV_Validator valid ) 00737 { 00738 FT_Bytes p = table; 00739 FT_UInt PosFormat; 00740 00741 00742 OTV_NAME_ENTER( "MarkMarkPos" ); 00743 00744 OTV_LIMIT_CHECK( 2 ); 00745 PosFormat = FT_NEXT_USHORT( p ); 00746 00747 OTV_TRACE(( " (format %d)\n", PosFormat )); 00748 00749 switch ( PosFormat ) 00750 { 00751 case 1: 00752 valid->extra2 = 0; 00753 OTV_NEST2( MarkMarkPosFormat1, Mark2Array ); 00754 OTV_RUN( table, valid ); 00755 break; 00756 00757 default: 00758 FT_INVALID_FORMAT; 00759 } 00760 00761 OTV_EXIT; 00762 } 00763 00764 00765 /*************************************************************************/ 00766 /*************************************************************************/ 00767 /***** *****/ 00768 /***** GPOS LOOKUP TYPE 7 *****/ 00769 /***** *****/ 00770 /*************************************************************************/ 00771 /*************************************************************************/ 00772 00773 /* sets valid->extra1 (lookup count) */ 00774 00775 static void 00776 otv_ContextPos_validate( FT_Bytes table, 00777 OTV_Validator valid ) 00778 { 00779 FT_Bytes p = table; 00780 FT_UInt PosFormat; 00781 00782 00783 OTV_NAME_ENTER( "ContextPos" ); 00784 00785 OTV_LIMIT_CHECK( 2 ); 00786 PosFormat = FT_NEXT_USHORT( p ); 00787 00788 OTV_TRACE(( " (format %d)\n", PosFormat )); 00789 00790 switch ( PosFormat ) 00791 { 00792 case 1: 00793 /* no need to check glyph indices/classes used as input for these */ 00794 /* context rules since even invalid glyph indices/classes return */ 00795 /* meaningful results */ 00796 00797 valid->extra1 = valid->lookup_count; 00798 OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule ); 00799 OTV_RUN( table, valid ); 00800 break; 00801 00802 case 2: 00803 /* no need to check glyph indices/classes used as input for these */ 00804 /* context rules since even invalid glyph indices/classes return */ 00805 /* meaningful results */ 00806 00807 OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule ); 00808 OTV_RUN( table, valid ); 00809 break; 00810 00811 case 3: 00812 OTV_NEST1( ContextPosFormat3 ); 00813 OTV_RUN( table, valid ); 00814 break; 00815 00816 default: 00817 FT_INVALID_FORMAT; 00818 } 00819 00820 OTV_EXIT; 00821 } 00822 00823 00824 /*************************************************************************/ 00825 /*************************************************************************/ 00826 /***** *****/ 00827 /***** GPOS LOOKUP TYPE 8 *****/ 00828 /***** *****/ 00829 /*************************************************************************/ 00830 /*************************************************************************/ 00831 00832 /* sets valid->extra1 (lookup count) */ 00833 00834 static void 00835 otv_ChainContextPos_validate( FT_Bytes table, 00836 OTV_Validator valid ) 00837 { 00838 FT_Bytes p = table; 00839 FT_UInt PosFormat; 00840 00841 00842 OTV_NAME_ENTER( "ChainContextPos" ); 00843 00844 OTV_LIMIT_CHECK( 2 ); 00845 PosFormat = FT_NEXT_USHORT( p ); 00846 00847 OTV_TRACE(( " (format %d)\n", PosFormat )); 00848 00849 switch ( PosFormat ) 00850 { 00851 case 1: 00852 /* no need to check glyph indices/classes used as input for these */ 00853 /* context rules since even invalid glyph indices/classes return */ 00854 /* meaningful results */ 00855 00856 valid->extra1 = valid->lookup_count; 00857 OTV_NEST3( ChainContextPosFormat1, 00858 ChainPosRuleSet, ChainPosRule ); 00859 OTV_RUN( table, valid ); 00860 break; 00861 00862 case 2: 00863 /* no need to check glyph indices/classes used as input for these */ 00864 /* context rules since even invalid glyph indices/classes return */ 00865 /* meaningful results */ 00866 00867 OTV_NEST3( ChainContextPosFormat2, 00868 ChainPosClassSet, ChainPosClassRule ); 00869 OTV_RUN( table, valid ); 00870 break; 00871 00872 case 3: 00873 OTV_NEST1( ChainContextPosFormat3 ); 00874 OTV_RUN( table, valid ); 00875 break; 00876 00877 default: 00878 FT_INVALID_FORMAT; 00879 } 00880 00881 OTV_EXIT; 00882 } 00883 00884 00885 /*************************************************************************/ 00886 /*************************************************************************/ 00887 /***** *****/ 00888 /***** GPOS LOOKUP TYPE 9 *****/ 00889 /***** *****/ 00890 /*************************************************************************/ 00891 /*************************************************************************/ 00892 00893 /* uses valid->type_funcs */ 00894 00895 static void 00896 otv_ExtensionPos_validate( FT_Bytes table, 00897 OTV_Validator valid ) 00898 { 00899 FT_Bytes p = table; 00900 FT_UInt PosFormat; 00901 00902 00903 OTV_NAME_ENTER( "ExtensionPos" ); 00904 00905 OTV_LIMIT_CHECK( 2 ); 00906 PosFormat = FT_NEXT_USHORT( p ); 00907 00908 OTV_TRACE(( " (format %d)\n", PosFormat )); 00909 00910 switch ( PosFormat ) 00911 { 00912 case 1: /* ExtensionPosFormat1 */ 00913 { 00914 FT_UInt ExtensionLookupType; 00915 FT_ULong ExtensionOffset; 00916 OTV_Validate_Func validate; 00917 00918 00919 OTV_LIMIT_CHECK( 6 ); 00920 ExtensionLookupType = FT_NEXT_USHORT( p ); 00921 ExtensionOffset = FT_NEXT_ULONG( p ); 00922 00923 if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 ) 00924 FT_INVALID_DATA; 00925 00926 validate = valid->type_funcs[ExtensionLookupType - 1]; 00927 validate( table + ExtensionOffset, valid ); 00928 } 00929 break; 00930 00931 default: 00932 FT_INVALID_FORMAT; 00933 } 00934 00935 OTV_EXIT; 00936 } 00937 00938 00939 static const OTV_Validate_Func otv_gpos_validate_funcs[9] = 00940 { 00941 otv_SinglePos_validate, 00942 otv_PairPos_validate, 00943 otv_CursivePos_validate, 00944 otv_MarkBasePos_validate, 00945 otv_MarkLigPos_validate, 00946 otv_MarkMarkPos_validate, 00947 otv_ContextPos_validate, 00948 otv_ChainContextPos_validate, 00949 otv_ExtensionPos_validate 00950 }; 00951 00952 00953 /* sets valid->type_count */ 00954 /* sets valid->type_funcs */ 00955 00956 FT_LOCAL_DEF( void ) 00957 otv_GPOS_subtable_validate( FT_Bytes table, 00958 OTV_Validator valid ) 00959 { 00960 valid->type_count = 9; 00961 valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; 00962 00963 otv_Lookup_validate( table, valid ); 00964 } 00965 00966 00967 /*************************************************************************/ 00968 /*************************************************************************/ 00969 /***** *****/ 00970 /***** GPOS TABLE *****/ 00971 /***** *****/ 00972 /*************************************************************************/ 00973 /*************************************************************************/ 00974 00975 /* sets valid->glyph_count */ 00976 00977 FT_LOCAL_DEF( void ) 00978 otv_GPOS_validate( FT_Bytes table, 00979 FT_UInt glyph_count, 00980 FT_Validator ftvalid ) 00981 { 00982 OTV_ValidatorRec validrec; 00983 OTV_Validator valid = &validrec; 00984 FT_Bytes p = table; 00985 FT_UInt ScriptList, FeatureList, LookupList; 00986 00987 00988 valid->root = ftvalid; 00989 00990 FT_TRACE3(( "validating GPOS table\n" )); 00991 OTV_INIT; 00992 00993 OTV_LIMIT_CHECK( 10 ); 00994 00995 if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ 00996 FT_INVALID_FORMAT; 00997 00998 ScriptList = FT_NEXT_USHORT( p ); 00999 FeatureList = FT_NEXT_USHORT( p ); 01000 LookupList = FT_NEXT_USHORT( p ); 01001 01002 valid->type_count = 9; 01003 valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs; 01004 valid->glyph_count = glyph_count; 01005 01006 otv_LookupList_validate( table + LookupList, 01007 valid ); 01008 otv_FeatureList_validate( table + FeatureList, table + LookupList, 01009 valid ); 01010 otv_ScriptList_validate( table + ScriptList, table + FeatureList, 01011 valid ); 01012 01013 FT_TRACE4(( "\n" )); 01014 } 01015 01016 01017 /* END */ Generated on Sat May 26 2012 04:32:45 for ReactOS by
1.7.6.1
|