31#define FT_COMPONENT otvgpos
35 otv_Anchor_validate( FT_Bytes table,
36 OTV_Validator valid );
39 otv_MarkArray_validate( FT_Bytes table,
40 OTV_Validator valid );
51#define BaseArrayFunc otv_x_sxy
52#define LigatureAttachFunc otv_x_sxy
53#define Mark2ArrayFunc otv_x_sxy
59 otv_x_sxy( FT_Bytes table,
60 OTV_Validator otvalid )
63 FT_UInt Count, count1, table_size;
70 Count = FT_NEXT_USHORT( p );
72 OTV_TRACE((
" (Count = %u)\n", Count ));
74 OTV_LIMIT_CHECK( Count * otvalid->extra1 * 2 );
76 table_size = Count * otvalid->extra1 * 2 + 2;
78 for ( ; Count > 0; Count-- )
79 for ( count1 = otvalid->extra1; count1 > 0; count1-- )
81 OTV_OPTIONAL_TABLE( anchor_offset );
84 OTV_OPTIONAL_OFFSET( anchor_offset );
86 if ( otvalid->extra2 )
88 OTV_SIZE_CHECK( anchor_offset );
90 otv_Anchor_validate( table + anchor_offset, otvalid );
93 otv_Anchor_validate( table + anchor_offset, otvalid );
100#define MarkBasePosFormat1Func otv_u_O_O_u_O_O
101#define MarkLigPosFormat1Func otv_u_O_O_u_O_O
102#define MarkMarkPosFormat1Func otv_u_O_O_u_O_O
107 otv_u_O_O_u_O_O( FT_Bytes table,
108 OTV_Validator otvalid )
111 FT_UInt Coverage1, Coverage2, ClassCount;
112 FT_UInt Array1, Array2;
113 OTV_Validate_Func func;
120 OTV_LIMIT_CHECK( 10 );
121 Coverage1 = FT_NEXT_USHORT( p );
122 Coverage2 = FT_NEXT_USHORT( p );
123 ClassCount = FT_NEXT_USHORT( p );
124 Array1 = FT_NEXT_USHORT( p );
125 Array2 = FT_NEXT_USHORT( p );
127 otv_Coverage_validate( table + Coverage1, otvalid, -1 );
128 otv_Coverage_validate( table + Coverage2, otvalid, -1 );
130 otv_MarkArray_validate( table + Array1, otvalid );
132 otvalid->nesting_level++;
133 func = otvalid->func[otvalid->nesting_level];
134 otvalid->extra1 = ClassCount;
136 func( table + Array2, otvalid );
138 otvalid->nesting_level--;
153 otv_value_length( FT_UInt format )
158 count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 );
159 count = ( ( count & 0xCC ) >> 2 ) + ( count & 0x33 );
160 count = ( ( count & 0xF0 ) >> 4 ) + ( count & 0x0F );
169 otv_ValueRecord_validate( FT_Bytes table,
171 OTV_Validator otvalid )
176#ifdef FT_DEBUG_LEVEL_TRACE
181 OTV_NAME_ENTER(
"ValueRecord" );
184 for ( loop = 7; loop >= 0; loop-- )
187 res += ( format >> loop ) & 1;
190 OTV_TRACE((
" (format 0b%08lx)\n", res ));
193 if ( format >= 0x100 )
196 for ( count = 4; count > 0; count-- )
201 OTV_LIMIT_CHECK( 2 );
208 for ( count = 4; count > 0; count-- )
212 FT_PtrDist table_size;
214 OTV_OPTIONAL_TABLE( device );
218 OTV_LIMIT_CHECK( 2 );
219 OTV_OPTIONAL_OFFSET( device );
221 table_size = p - otvalid->extra3;
223 OTV_SIZE_CHECK( device );
225 otv_Device_validate( otvalid->extra3 + device, otvalid );
243 otv_Anchor_validate( FT_Bytes table,
244 OTV_Validator otvalid )
247 FT_UInt AnchorFormat;
250 OTV_NAME_ENTER(
"Anchor");
252 OTV_LIMIT_CHECK( 6 );
253 AnchorFormat = FT_NEXT_USHORT( p );
255 OTV_TRACE((
" (format %u)\n", AnchorFormat ));
259 switch ( AnchorFormat )
265 OTV_LIMIT_CHECK( 2 );
272 OTV_OPTIONAL_TABLE( XDeviceTable );
273 OTV_OPTIONAL_TABLE( YDeviceTable );
276 OTV_LIMIT_CHECK( 4 );
277 OTV_OPTIONAL_OFFSET( XDeviceTable );
278 OTV_OPTIONAL_OFFSET( YDeviceTable );
282 OTV_SIZE_CHECK( XDeviceTable );
284 otv_Device_validate( table + XDeviceTable, otvalid );
286 OTV_SIZE_CHECK( YDeviceTable );
288 otv_Device_validate( table + YDeviceTable, otvalid );
309 otv_MarkArray_validate( FT_Bytes table,
310 OTV_Validator otvalid )
316 OTV_NAME_ENTER(
"MarkArray" );
318 OTV_LIMIT_CHECK( 2 );
319 MarkCount = FT_NEXT_USHORT( p );
321 OTV_TRACE((
" (MarkCount = %u)\n", MarkCount ));
323 OTV_LIMIT_CHECK( MarkCount * 4 );
326 for ( ; MarkCount > 0; MarkCount-- )
330 otv_Anchor_validate( table + FT_NEXT_USHORT( p ), otvalid );
348 otv_SinglePos_validate( FT_Bytes table,
349 OTV_Validator otvalid )
355 OTV_NAME_ENTER(
"SinglePos" );
357 OTV_LIMIT_CHECK( 2 );
358 PosFormat = FT_NEXT_USHORT( p );
360 OTV_TRACE((
" (format %u)\n", PosFormat ));
362 otvalid->extra3 = table;
368 FT_UInt Coverage, ValueFormat;
371 OTV_LIMIT_CHECK( 4 );
372 Coverage = FT_NEXT_USHORT( p );
373 ValueFormat = FT_NEXT_USHORT( p );
375 otv_Coverage_validate( table + Coverage, otvalid, -1 );
376 otv_ValueRecord_validate( p, ValueFormat, otvalid );
382 FT_UInt Coverage, ValueFormat, ValueCount, len_value;
385 OTV_LIMIT_CHECK( 6 );
386 Coverage = FT_NEXT_USHORT( p );
387 ValueFormat = FT_NEXT_USHORT( p );
388 ValueCount = FT_NEXT_USHORT( p );
390 OTV_TRACE((
" (ValueCount = %u)\n", ValueCount ));
392 len_value = otv_value_length( ValueFormat );
394 otv_Coverage_validate( table + Coverage,
396 (FT_Int)ValueCount );
398 OTV_LIMIT_CHECK( ValueCount * len_value );
401 for ( ; ValueCount > 0; ValueCount-- )
403 otv_ValueRecord_validate( p, ValueFormat, otvalid );
428 otv_PairSet_validate( FT_Bytes table,
431 OTV_Validator otvalid )
434 FT_UInt value_len1, value_len2, PairValueCount;
437 OTV_NAME_ENTER(
"PairSet" );
439 otvalid->extra3 = table;
441 OTV_LIMIT_CHECK( 2 );
442 PairValueCount = FT_NEXT_USHORT( p );
444 OTV_TRACE((
" (PairValueCount = %u)\n", PairValueCount ));
446 value_len1 = otv_value_length( format1 );
447 value_len2 = otv_value_length( format2 );
449 OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) );
452 for ( ; PairValueCount > 0; PairValueCount-- )
457 otv_ValueRecord_validate( p, format1, otvalid );
461 otv_ValueRecord_validate( p, format2, otvalid );
472 otv_PairPos_validate( FT_Bytes table,
473 OTV_Validator otvalid )
479 OTV_NAME_ENTER(
"PairPos" );
481 OTV_LIMIT_CHECK( 2 );
482 PosFormat = FT_NEXT_USHORT( p );
484 OTV_TRACE((
" (format %u)\n", PosFormat ));
490 FT_UInt Coverage, ValueFormat1, ValueFormat2, PairSetCount;
493 OTV_LIMIT_CHECK( 8 );
494 Coverage = FT_NEXT_USHORT( p );
495 ValueFormat1 = FT_NEXT_USHORT( p );
496 ValueFormat2 = FT_NEXT_USHORT( p );
497 PairSetCount = FT_NEXT_USHORT( p );
499 OTV_TRACE((
" (PairSetCount = %u)\n", PairSetCount ));
501 otv_Coverage_validate( table + Coverage, otvalid, -1 );
503 OTV_LIMIT_CHECK( PairSetCount * 2 );
506 for ( ; PairSetCount > 0; PairSetCount-- )
507 otv_PairSet_validate( table + FT_NEXT_USHORT( p ),
508 ValueFormat1, ValueFormat2, otvalid );
514 FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2;
515 FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count;
518 OTV_LIMIT_CHECK( 14 );
519 Coverage = FT_NEXT_USHORT( p );
520 ValueFormat1 = FT_NEXT_USHORT( p );
521 ValueFormat2 = FT_NEXT_USHORT( p );
522 ClassDef1 = FT_NEXT_USHORT( p );
523 ClassDef2 = FT_NEXT_USHORT( p );
524 ClassCount1 = FT_NEXT_USHORT( p );
525 ClassCount2 = FT_NEXT_USHORT( p );
527 OTV_TRACE((
" (ClassCount1 = %u)\n", ClassCount1 ));
528 OTV_TRACE((
" (ClassCount2 = %u)\n", ClassCount2 ));
530 len_value1 = otv_value_length( ValueFormat1 );
531 len_value2 = otv_value_length( ValueFormat2 );
533 otv_Coverage_validate( table + Coverage, otvalid, -1 );
534 otv_ClassDef_validate( table + ClassDef1, otvalid );
535 otv_ClassDef_validate( table + ClassDef2, otvalid );
537 OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 *
538 ( len_value1 + len_value2 ) );
540 otvalid->extra3 = table;
543 for ( ; ClassCount1 > 0; ClassCount1-- )
546 for ( count = ClassCount2; count > 0; count-- )
550 otv_ValueRecord_validate( p, ValueFormat1, otvalid );
555 otv_ValueRecord_validate( p, ValueFormat2, otvalid );
579 otv_CursivePos_validate( FT_Bytes table,
580 OTV_Validator otvalid )
586 OTV_NAME_ENTER(
"CursivePos" );
588 OTV_LIMIT_CHECK( 2 );
589 PosFormat = FT_NEXT_USHORT( p );
591 OTV_TRACE((
" (format %u)\n", PosFormat ));
598 FT_UInt Coverage, EntryExitCount;
600 OTV_OPTIONAL_TABLE( EntryAnchor );
601 OTV_OPTIONAL_TABLE( ExitAnchor );
604 OTV_LIMIT_CHECK( 4 );
605 Coverage = FT_NEXT_USHORT( p );
606 EntryExitCount = FT_NEXT_USHORT( p );
608 OTV_TRACE((
" (EntryExitCount = %u)\n", EntryExitCount ));
610 otv_Coverage_validate( table + Coverage,
612 (FT_Int)EntryExitCount );
614 OTV_LIMIT_CHECK( EntryExitCount * 4 );
616 table_size = EntryExitCount * 4 + 4;
619 for ( ; EntryExitCount > 0; EntryExitCount-- )
621 OTV_OPTIONAL_OFFSET( EntryAnchor );
622 OTV_OPTIONAL_OFFSET( ExitAnchor );
624 OTV_SIZE_CHECK( EntryAnchor );
626 otv_Anchor_validate( table + EntryAnchor, otvalid );
628 OTV_SIZE_CHECK( ExitAnchor );
630 otv_Anchor_validate( table + ExitAnchor, otvalid );
657 otv_MarkBasePos_validate( FT_Bytes table,
658 OTV_Validator otvalid )
664 OTV_NAME_ENTER(
"MarkBasePos" );
666 OTV_LIMIT_CHECK( 2 );
667 PosFormat = FT_NEXT_USHORT( p );
669 OTV_TRACE((
" (format %u)\n", PosFormat ));
675 OTV_NEST2( MarkBasePosFormat1, BaseArray );
676 OTV_RUN( table, otvalid );
698 otv_MarkLigPos_validate( FT_Bytes table,
699 OTV_Validator otvalid )
705 OTV_NAME_ENTER(
"MarkLigPos" );
707 OTV_LIMIT_CHECK( 2 );
708 PosFormat = FT_NEXT_USHORT( p );
710 OTV_TRACE((
" (format %u)\n", PosFormat ));
716 OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach );
717 OTV_RUN( table, otvalid );
739 otv_MarkMarkPos_validate( FT_Bytes table,
740 OTV_Validator otvalid )
746 OTV_NAME_ENTER(
"MarkMarkPos" );
748 OTV_LIMIT_CHECK( 2 );
749 PosFormat = FT_NEXT_USHORT( p );
751 OTV_TRACE((
" (format %u)\n", PosFormat ));
757 OTV_NEST2( MarkMarkPosFormat1, Mark2Array );
758 OTV_RUN( table, otvalid );
780 otv_ContextPos_validate( FT_Bytes table,
781 OTV_Validator otvalid )
787 OTV_NAME_ENTER(
"ContextPos" );
789 OTV_LIMIT_CHECK( 2 );
790 PosFormat = FT_NEXT_USHORT( p );
792 OTV_TRACE((
" (format %u)\n", PosFormat ));
801 otvalid->extra1 = otvalid->lookup_count;
802 OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule );
803 OTV_RUN( table, otvalid );
811 OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule );
812 OTV_RUN( table, otvalid );
816 OTV_NEST1( ContextPosFormat3 );
817 OTV_RUN( table, otvalid );
839 otv_ChainContextPos_validate( FT_Bytes table,
840 OTV_Validator otvalid )
846 OTV_NAME_ENTER(
"ChainContextPos" );
848 OTV_LIMIT_CHECK( 2 );
849 PosFormat = FT_NEXT_USHORT( p );
851 OTV_TRACE((
" (format %u)\n", PosFormat ));
860 otvalid->extra1 = otvalid->lookup_count;
861 OTV_NEST3( ChainContextPosFormat1,
862 ChainPosRuleSet, ChainPosRule );
863 OTV_RUN( table, otvalid );
871 OTV_NEST3( ChainContextPosFormat2,
872 ChainPosClassSet, ChainPosClassRule );
873 OTV_RUN( table, otvalid );
877 OTV_NEST1( ChainContextPosFormat3 );
878 OTV_RUN( table, otvalid );
900 otv_ExtensionPos_validate( FT_Bytes table,
901 OTV_Validator otvalid )
907 OTV_NAME_ENTER(
"ExtensionPos" );
909 OTV_LIMIT_CHECK( 2 );
910 PosFormat = FT_NEXT_USHORT( p );
912 OTV_TRACE((
" (format %u)\n", PosFormat ));
918 FT_UInt ExtensionLookupType;
919 FT_ULong ExtensionOffset;
920 OTV_Validate_Func validate;
923 OTV_LIMIT_CHECK( 6 );
924 ExtensionLookupType = FT_NEXT_USHORT( p );
925 ExtensionOffset = FT_NEXT_ULONG( p );
927 if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 )
930 validate = otvalid->type_funcs[ExtensionLookupType - 1];
931 validate( table + ExtensionOffset, otvalid );
943 static const OTV_Validate_Func otv_gpos_validate_funcs[9] =
945 otv_SinglePos_validate,
946 otv_PairPos_validate,
947 otv_CursivePos_validate,
948 otv_MarkBasePos_validate,
949 otv_MarkLigPos_validate,
950 otv_MarkMarkPos_validate,
951 otv_ContextPos_validate,
952 otv_ChainContextPos_validate,
953 otv_ExtensionPos_validate
961 otv_GPOS_subtable_validate( FT_Bytes table,
962 OTV_Validator otvalid )
964 otvalid->type_count = 9;
965 otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
967 otv_Lookup_validate( table, otvalid );
982 otv_GPOS_validate( FT_Bytes table,
984 FT_Validator ftvalid )
986 OTV_ValidatorRec validrec;
987 OTV_Validator otvalid = &validrec;
991 FT_UInt ScriptList, FeatureList, LookupList;
993 OTV_OPTIONAL_TABLE32( featureVariations );
996 otvalid->root = ftvalid;
998 FT_TRACE3((
"validating GPOS table\n" ));
1001 OTV_LIMIT_CHECK( 4 );
1003 if ( FT_NEXT_USHORT( p ) != 1 )
1006 version = FT_NEXT_USHORT( p );
1012 OTV_LIMIT_CHECK( 6 );
1016 OTV_LIMIT_CHECK( 10 );
1024 ScriptList = FT_NEXT_USHORT( p );
1025 FeatureList = FT_NEXT_USHORT( p );
1026 LookupList = FT_NEXT_USHORT( p );
1028 otvalid->type_count = 9;
1029 otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
1030 otvalid->glyph_count = glyph_count;
1032 otv_LookupList_validate( table + LookupList,
1034 otv_FeatureList_validate( table + FeatureList, table + LookupList,
1036 otv_ScriptList_validate( table + ScriptList, table + FeatureList,
1041 OTV_OPTIONAL_OFFSET32( featureVariations );
1042 OTV_SIZE_CHECK32( featureVariations );
1043 if ( featureVariations )
1044 OTV_TRACE((
" [omitting featureVariations validation]\n" ));
1047 FT_TRACE4((
"\n" ));