mgh: fix for default HDD DMA mode, that wasn't correctly set
[open-ps2-loader.git] / thirdparty / freetype-2.3.12 / src / otvalid / otvcommn.c
bloba4f885b51f84f8a1cc0dc9aae07504e1397bc7a8
1 /***************************************************************************/
2 /* */
3 /* otvcommn.c */
4 /* */
5 /* OpenType common tables validation (body). */
6 /* */
7 /* Copyright 2004, 2005, 2006, 2007 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
19 #include "otvcommn.h"
22 /*************************************************************************/
23 /* */
24 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
25 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
26 /* messages during execution. */
27 /* */
28 #undef FT_COMPONENT
29 #define FT_COMPONENT trace_otvcommon
32 /*************************************************************************/
33 /*************************************************************************/
34 /***** *****/
35 /***** COVERAGE TABLE *****/
36 /***** *****/
37 /*************************************************************************/
38 /*************************************************************************/
40 FT_LOCAL_DEF( void )
41 otv_Coverage_validate( FT_Bytes table,
42 OTV_Validator valid,
43 FT_Int expected_count )
45 FT_Bytes p = table;
46 FT_UInt CoverageFormat;
47 FT_UInt total = 0;
50 OTV_NAME_ENTER( "Coverage" );
52 OTV_LIMIT_CHECK( 4 );
53 CoverageFormat = FT_NEXT_USHORT( p );
55 OTV_TRACE(( " (format %d)\n", CoverageFormat ));
57 switch ( CoverageFormat )
59 case 1: /* CoverageFormat1 */
61 FT_UInt GlyphCount;
62 FT_UInt i;
65 GlyphCount = FT_NEXT_USHORT( p );
67 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
69 OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */
71 for ( i = 0; i < GlyphCount; ++i )
73 FT_UInt gid;
76 gid = FT_NEXT_USHORT( p );
77 if ( gid >= valid->glyph_count )
78 FT_INVALID_GLYPH_ID;
81 total = GlyphCount;
83 break;
85 case 2: /* CoverageFormat2 */
87 FT_UInt n, RangeCount;
88 FT_UInt Start, End, StartCoverageIndex, last = 0;
91 RangeCount = FT_NEXT_USHORT( p );
93 OTV_TRACE(( " (RangeCount = %d)\n", RangeCount ));
95 OTV_LIMIT_CHECK( RangeCount * 6 );
97 /* RangeRecord */
98 for ( n = 0; n < RangeCount; n++ )
100 Start = FT_NEXT_USHORT( p );
101 End = FT_NEXT_USHORT( p );
102 StartCoverageIndex = FT_NEXT_USHORT( p );
104 if ( Start > End || StartCoverageIndex != total )
105 FT_INVALID_DATA;
107 if ( End >= valid->glyph_count )
108 FT_INVALID_GLYPH_ID;
110 if ( n > 0 && Start <= last )
111 FT_INVALID_DATA;
113 total += End - Start + 1;
114 last = End;
117 break;
119 default:
120 FT_INVALID_FORMAT;
123 /* Generally, a coverage table offset has an associated count field. */
124 /* The number of glyphs in the table should match this field. If */
125 /* there is no associated count, a value of -1 tells us not to check. */
126 if ( expected_count != -1 && (FT_UInt)expected_count != total )
127 FT_INVALID_DATA;
129 OTV_EXIT;
133 FT_LOCAL_DEF( FT_UInt )
134 otv_Coverage_get_first( FT_Bytes table )
136 FT_Bytes p = table;
139 p += 4; /* skip CoverageFormat and Glyph/RangeCount */
141 return FT_NEXT_USHORT( p );
145 FT_LOCAL_DEF( FT_UInt )
146 otv_Coverage_get_last( FT_Bytes table )
148 FT_Bytes p = table;
149 FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
150 FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */
151 FT_UInt result = 0;
154 switch ( CoverageFormat )
156 case 1:
157 p += ( count - 1 ) * 2;
158 result = FT_NEXT_USHORT( p );
159 break;
161 case 2:
162 p += ( count - 1 ) * 6 + 2;
163 result = FT_NEXT_USHORT( p );
164 break;
166 default:
170 return result;
174 FT_LOCAL_DEF( FT_UInt )
175 otv_Coverage_get_count( FT_Bytes table )
177 FT_Bytes p = table;
178 FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
179 FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */
180 FT_UInt result = 0;
183 switch ( CoverageFormat )
185 case 1:
186 return count;
188 case 2:
190 FT_UInt Start, End;
193 for ( ; count > 0; count-- )
195 Start = FT_NEXT_USHORT( p );
196 End = FT_NEXT_USHORT( p );
197 p += 2; /* skip StartCoverageIndex */
199 result += End - Start + 1;
202 break;
204 default:
208 return result;
212 /*************************************************************************/
213 /*************************************************************************/
214 /***** *****/
215 /***** CLASS DEFINITION TABLE *****/
216 /***** *****/
217 /*************************************************************************/
218 /*************************************************************************/
220 FT_LOCAL_DEF( void )
221 otv_ClassDef_validate( FT_Bytes table,
222 OTV_Validator valid )
224 FT_Bytes p = table;
225 FT_UInt ClassFormat;
228 OTV_NAME_ENTER( "ClassDef" );
230 OTV_LIMIT_CHECK( 4 );
231 ClassFormat = FT_NEXT_USHORT( p );
233 OTV_TRACE(( " (format %d)\n", ClassFormat ));
235 switch ( ClassFormat )
237 case 1: /* ClassDefFormat1 */
239 FT_UInt StartGlyph;
240 FT_UInt GlyphCount;
243 OTV_LIMIT_CHECK( 4 );
245 StartGlyph = FT_NEXT_USHORT( p );
246 GlyphCount = FT_NEXT_USHORT( p );
248 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
250 OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */
252 if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
253 FT_INVALID_GLYPH_ID;
255 break;
257 case 2: /* ClassDefFormat2 */
259 FT_UInt n, ClassRangeCount;
260 FT_UInt Start, End, last = 0;
263 ClassRangeCount = FT_NEXT_USHORT( p );
265 OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount ));
267 OTV_LIMIT_CHECK( ClassRangeCount * 6 );
269 /* ClassRangeRecord */
270 for ( n = 0; n < ClassRangeCount; n++ )
272 Start = FT_NEXT_USHORT( p );
273 End = FT_NEXT_USHORT( p );
274 p += 2; /* skip Class */
276 if ( Start > End || ( n > 0 && Start <= last ) )
277 FT_INVALID_DATA;
279 if ( End >= valid->glyph_count )
280 FT_INVALID_GLYPH_ID;
282 last = End;
285 break;
287 default:
288 FT_INVALID_FORMAT;
291 /* no need to check glyph indices used as input to class definition */
292 /* tables since even invalid glyph indices return a meaningful result */
294 OTV_EXIT;
298 /*************************************************************************/
299 /*************************************************************************/
300 /***** *****/
301 /***** DEVICE TABLE *****/
302 /***** *****/
303 /*************************************************************************/
304 /*************************************************************************/
306 FT_LOCAL_DEF( void )
307 otv_Device_validate( FT_Bytes table,
308 OTV_Validator valid )
310 FT_Bytes p = table;
311 FT_UInt StartSize, EndSize, DeltaFormat, count;
314 OTV_NAME_ENTER( "Device" );
316 OTV_LIMIT_CHECK( 8 );
317 StartSize = FT_NEXT_USHORT( p );
318 EndSize = FT_NEXT_USHORT( p );
319 DeltaFormat = FT_NEXT_USHORT( p );
321 if ( DeltaFormat < 1 || DeltaFormat > 3 )
322 FT_INVALID_FORMAT;
324 if ( EndSize < StartSize )
325 FT_INVALID_DATA;
327 count = EndSize - StartSize + 1;
328 OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */
330 OTV_EXIT;
334 /*************************************************************************/
335 /*************************************************************************/
336 /***** *****/
337 /***** LOOKUPS *****/
338 /***** *****/
339 /*************************************************************************/
340 /*************************************************************************/
342 /* uses valid->type_count */
343 /* uses valid->type_funcs */
345 FT_LOCAL_DEF( void )
346 otv_Lookup_validate( FT_Bytes table,
347 OTV_Validator valid )
349 FT_Bytes p = table;
350 FT_UInt LookupType, SubTableCount;
351 OTV_Validate_Func validate;
354 OTV_NAME_ENTER( "Lookup" );
356 OTV_LIMIT_CHECK( 6 );
357 LookupType = FT_NEXT_USHORT( p );
358 p += 2; /* skip LookupFlag */
359 SubTableCount = FT_NEXT_USHORT( p );
361 OTV_TRACE(( " (type %d)\n", LookupType ));
363 if ( LookupType == 0 || LookupType > valid->type_count )
364 FT_INVALID_DATA;
366 validate = valid->type_funcs[LookupType - 1];
368 OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount ));
370 OTV_LIMIT_CHECK( SubTableCount * 2 );
372 /* SubTable */
373 for ( ; SubTableCount > 0; SubTableCount-- )
374 validate( table + FT_NEXT_USHORT( p ), valid );
376 OTV_EXIT;
380 /* uses valid->lookup_count */
382 FT_LOCAL_DEF( void )
383 otv_LookupList_validate( FT_Bytes table,
384 OTV_Validator valid )
386 FT_Bytes p = table;
387 FT_UInt LookupCount;
390 OTV_NAME_ENTER( "LookupList" );
392 OTV_LIMIT_CHECK( 2 );
393 LookupCount = FT_NEXT_USHORT( p );
395 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
397 OTV_LIMIT_CHECK( LookupCount * 2 );
399 valid->lookup_count = LookupCount;
401 /* Lookup */
402 for ( ; LookupCount > 0; LookupCount-- )
403 otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid );
405 OTV_EXIT;
409 static FT_UInt
410 otv_LookupList_get_count( FT_Bytes table )
412 return FT_NEXT_USHORT( table );
416 /*************************************************************************/
417 /*************************************************************************/
418 /***** *****/
419 /***** FEATURES *****/
420 /***** *****/
421 /*************************************************************************/
422 /*************************************************************************/
424 /* uses valid->lookup_count */
426 FT_LOCAL_DEF( void )
427 otv_Feature_validate( FT_Bytes table,
428 OTV_Validator valid )
430 FT_Bytes p = table;
431 FT_UInt LookupCount;
434 OTV_NAME_ENTER( "Feature" );
436 OTV_LIMIT_CHECK( 4 );
437 p += 2; /* skip FeatureParams (unused) */
438 LookupCount = FT_NEXT_USHORT( p );
440 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
442 OTV_LIMIT_CHECK( LookupCount * 2 );
444 /* LookupListIndex */
445 for ( ; LookupCount > 0; LookupCount-- )
446 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
447 FT_INVALID_DATA;
449 OTV_EXIT;
453 static FT_UInt
454 otv_Feature_get_count( FT_Bytes table )
456 return FT_NEXT_USHORT( table );
460 /* sets valid->lookup_count */
462 FT_LOCAL_DEF( void )
463 otv_FeatureList_validate( FT_Bytes table,
464 FT_Bytes lookups,
465 OTV_Validator valid )
467 FT_Bytes p = table;
468 FT_UInt FeatureCount;
471 OTV_NAME_ENTER( "FeatureList" );
473 OTV_LIMIT_CHECK( 2 );
474 FeatureCount = FT_NEXT_USHORT( p );
476 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
478 OTV_LIMIT_CHECK( FeatureCount * 2 );
480 valid->lookup_count = otv_LookupList_get_count( lookups );
482 /* FeatureRecord */
483 for ( ; FeatureCount > 0; FeatureCount-- )
485 p += 4; /* skip FeatureTag */
487 /* Feature */
488 otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid );
491 OTV_EXIT;
495 /*************************************************************************/
496 /*************************************************************************/
497 /***** *****/
498 /***** LANGUAGE SYSTEM *****/
499 /***** *****/
500 /*************************************************************************/
501 /*************************************************************************/
504 /* uses valid->extra1 (number of features) */
506 FT_LOCAL_DEF( void )
507 otv_LangSys_validate( FT_Bytes table,
508 OTV_Validator valid )
510 FT_Bytes p = table;
511 FT_UInt ReqFeatureIndex;
512 FT_UInt FeatureCount;
515 OTV_NAME_ENTER( "LangSys" );
517 OTV_LIMIT_CHECK( 6 );
518 p += 2; /* skip LookupOrder (unused) */
519 ReqFeatureIndex = FT_NEXT_USHORT( p );
520 FeatureCount = FT_NEXT_USHORT( p );
522 OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex ));
523 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
525 if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 )
526 FT_INVALID_DATA;
528 OTV_LIMIT_CHECK( FeatureCount * 2 );
530 /* FeatureIndex */
531 for ( ; FeatureCount > 0; FeatureCount-- )
532 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
533 FT_INVALID_DATA;
535 OTV_EXIT;
539 /*************************************************************************/
540 /*************************************************************************/
541 /***** *****/
542 /***** SCRIPTS *****/
543 /***** *****/
544 /*************************************************************************/
545 /*************************************************************************/
547 FT_LOCAL_DEF( void )
548 otv_Script_validate( FT_Bytes table,
549 OTV_Validator valid )
551 FT_UInt DefaultLangSys, LangSysCount;
552 FT_Bytes p = table;
555 OTV_NAME_ENTER( "Script" );
557 OTV_LIMIT_CHECK( 4 );
558 DefaultLangSys = FT_NEXT_USHORT( p );
559 LangSysCount = FT_NEXT_USHORT( p );
561 OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount ));
563 if ( DefaultLangSys != 0 )
564 otv_LangSys_validate( table + DefaultLangSys, valid );
566 OTV_LIMIT_CHECK( LangSysCount * 6 );
568 /* LangSysRecord */
569 for ( ; LangSysCount > 0; LangSysCount-- )
571 p += 4; /* skip LangSysTag */
573 /* LangSys */
574 otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid );
577 OTV_EXIT;
581 /* sets valid->extra1 (number of features) */
583 FT_LOCAL_DEF( void )
584 otv_ScriptList_validate( FT_Bytes table,
585 FT_Bytes features,
586 OTV_Validator valid )
588 FT_UInt ScriptCount;
589 FT_Bytes p = table;
592 OTV_NAME_ENTER( "ScriptList" );
594 OTV_LIMIT_CHECK( 2 );
595 ScriptCount = FT_NEXT_USHORT( p );
597 OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount ));
599 OTV_LIMIT_CHECK( ScriptCount * 6 );
601 valid->extra1 = otv_Feature_get_count( features );
603 /* ScriptRecord */
604 for ( ; ScriptCount > 0; ScriptCount-- )
606 p += 4; /* skip ScriptTag */
608 otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */
611 OTV_EXIT;
615 /*************************************************************************/
616 /*************************************************************************/
617 /***** *****/
618 /***** UTILITY FUNCTIONS *****/
619 /***** *****/
620 /*************************************************************************/
621 /*************************************************************************/
624 u: uint16
625 ux: unit16 [x]
627 s: struct
628 sx: struct [x]
629 sxy: struct [x], using external y count
631 x: uint16 x
633 C: Coverage
635 O: Offset
636 On: Offset (NULL)
637 Ox: Offset [x]
638 Onx: Offset (NULL) [x]
641 FT_LOCAL_DEF( void )
642 otv_x_Ox( FT_Bytes table,
643 OTV_Validator valid )
645 FT_Bytes p = table;
646 FT_UInt Count;
647 OTV_Validate_Func func;
650 OTV_ENTER;
652 OTV_LIMIT_CHECK( 2 );
653 Count = FT_NEXT_USHORT( p );
655 OTV_TRACE(( " (Count = %d)\n", Count ));
657 OTV_LIMIT_CHECK( Count * 2 );
659 valid->nesting_level++;
660 func = valid->func[valid->nesting_level];
662 for ( ; Count > 0; Count-- )
663 func( table + FT_NEXT_USHORT( p ), valid );
665 valid->nesting_level--;
667 OTV_EXIT;
671 FT_LOCAL_DEF( void )
672 otv_u_C_x_Ox( FT_Bytes table,
673 OTV_Validator valid )
675 FT_Bytes p = table;
676 FT_UInt Count, Coverage;
677 OTV_Validate_Func func;
680 OTV_ENTER;
682 p += 2; /* skip Format */
684 OTV_LIMIT_CHECK( 4 );
685 Coverage = FT_NEXT_USHORT( p );
686 Count = FT_NEXT_USHORT( p );
688 OTV_TRACE(( " (Count = %d)\n", Count ));
690 otv_Coverage_validate( table + Coverage, valid, Count );
692 OTV_LIMIT_CHECK( Count * 2 );
694 valid->nesting_level++;
695 func = valid->func[valid->nesting_level];
697 for ( ; Count > 0; Count-- )
698 func( table + FT_NEXT_USHORT( p ), valid );
700 valid->nesting_level--;
702 OTV_EXIT;
706 /* uses valid->extra1 (if > 0: array value limit) */
708 FT_LOCAL_DEF( void )
709 otv_x_ux( FT_Bytes table,
710 OTV_Validator valid )
712 FT_Bytes p = table;
713 FT_UInt Count;
716 OTV_ENTER;
718 OTV_LIMIT_CHECK( 2 );
719 Count = FT_NEXT_USHORT( p );
721 OTV_TRACE(( " (Count = %d)\n", Count ));
723 OTV_LIMIT_CHECK( Count * 2 );
725 if ( valid->extra1 )
727 for ( ; Count > 0; Count-- )
728 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
729 FT_INVALID_DATA;
732 OTV_EXIT;
736 /* `ux' in the function's name is not really correct since only x-1 */
737 /* elements are tested */
739 /* uses valid->extra1 (array value limit) */
741 FT_LOCAL_DEF( void )
742 otv_x_y_ux_sy( FT_Bytes table,
743 OTV_Validator valid )
745 FT_Bytes p = table;
746 FT_UInt Count1, Count2;
749 OTV_ENTER;
751 OTV_LIMIT_CHECK( 4 );
752 Count1 = FT_NEXT_USHORT( p );
753 Count2 = FT_NEXT_USHORT( p );
755 OTV_TRACE(( " (Count1 = %d)\n", Count1 ));
756 OTV_TRACE(( " (Count2 = %d)\n", Count2 ));
758 if ( Count1 == 0 )
759 FT_INVALID_DATA;
761 OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
762 p += ( Count1 - 1 ) * 2;
764 for ( ; Count2 > 0; Count2-- )
766 if ( FT_NEXT_USHORT( p ) >= Count1 )
767 FT_INVALID_DATA;
769 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
770 FT_INVALID_DATA;
773 OTV_EXIT;
777 /* `uy' in the function's name is not really correct since only y-1 */
778 /* elements are tested */
780 /* uses valid->extra1 (array value limit) */
782 FT_LOCAL_DEF( void )
783 otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table,
784 OTV_Validator valid )
786 FT_Bytes p = table;
787 FT_UInt BacktrackCount, InputCount, LookaheadCount;
788 FT_UInt Count;
791 OTV_ENTER;
793 OTV_LIMIT_CHECK( 2 );
794 BacktrackCount = FT_NEXT_USHORT( p );
796 OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount ));
798 OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 );
799 p += BacktrackCount * 2;
801 InputCount = FT_NEXT_USHORT( p );
802 if ( InputCount == 0 )
803 FT_INVALID_DATA;
805 OTV_TRACE(( " (InputCount = %d)\n", InputCount ));
807 OTV_LIMIT_CHECK( InputCount * 2 );
808 p += ( InputCount - 1 ) * 2;
810 LookaheadCount = FT_NEXT_USHORT( p );
812 OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount ));
814 OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 );
815 p += LookaheadCount * 2;
817 Count = FT_NEXT_USHORT( p );
819 OTV_TRACE(( " (Count = %d)\n", Count ));
821 OTV_LIMIT_CHECK( Count * 4 );
823 for ( ; Count > 0; Count-- )
825 if ( FT_NEXT_USHORT( p ) >= InputCount )
826 FT_INVALID_DATA;
828 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
829 FT_INVALID_DATA;
832 OTV_EXIT;
836 /* sets valid->extra1 (valid->lookup_count) */
838 FT_LOCAL_DEF( void )
839 otv_u_O_O_x_Onx( FT_Bytes table,
840 OTV_Validator valid )
842 FT_Bytes p = table;
843 FT_UInt Coverage, ClassDef, ClassSetCount;
844 OTV_Validate_Func func;
847 OTV_ENTER;
849 p += 2; /* skip Format */
851 OTV_LIMIT_CHECK( 6 );
852 Coverage = FT_NEXT_USHORT( p );
853 ClassDef = FT_NEXT_USHORT( p );
854 ClassSetCount = FT_NEXT_USHORT( p );
856 OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
858 otv_Coverage_validate( table + Coverage, valid, -1 );
859 otv_ClassDef_validate( table + ClassDef, valid );
861 OTV_LIMIT_CHECK( ClassSetCount * 2 );
863 valid->nesting_level++;
864 func = valid->func[valid->nesting_level];
865 valid->extra1 = valid->lookup_count;
867 for ( ; ClassSetCount > 0; ClassSetCount-- )
869 FT_UInt offset = FT_NEXT_USHORT( p );
872 if ( offset )
873 func( table + offset, valid );
876 valid->nesting_level--;
878 OTV_EXIT;
882 /* uses valid->lookup_count */
884 FT_LOCAL_DEF( void )
885 otv_u_x_y_Ox_sy( FT_Bytes table,
886 OTV_Validator valid )
888 FT_Bytes p = table;
889 FT_UInt GlyphCount, Count, count1;
892 OTV_ENTER;
894 p += 2; /* skip Format */
896 OTV_LIMIT_CHECK( 4 );
897 GlyphCount = FT_NEXT_USHORT( p );
898 Count = FT_NEXT_USHORT( p );
900 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
901 OTV_TRACE(( " (Count = %d)\n", Count ));
903 OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
905 for ( count1 = GlyphCount; count1 > 0; count1-- )
906 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
908 for ( ; Count > 0; Count-- )
910 if ( FT_NEXT_USHORT( p ) >= GlyphCount )
911 FT_INVALID_DATA;
913 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
914 FT_INVALID_DATA;
917 OTV_EXIT;
921 /* sets valid->extra1 (valid->lookup_count) */
923 FT_LOCAL_DEF( void )
924 otv_u_O_O_O_O_x_Onx( FT_Bytes table,
925 OTV_Validator valid )
927 FT_Bytes p = table;
928 FT_UInt Coverage;
929 FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef;
930 FT_UInt ChainClassSetCount;
931 OTV_Validate_Func func;
934 OTV_ENTER;
936 p += 2; /* skip Format */
938 OTV_LIMIT_CHECK( 10 );
939 Coverage = FT_NEXT_USHORT( p );
940 BacktrackClassDef = FT_NEXT_USHORT( p );
941 InputClassDef = FT_NEXT_USHORT( p );
942 LookaheadClassDef = FT_NEXT_USHORT( p );
943 ChainClassSetCount = FT_NEXT_USHORT( p );
945 OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
947 otv_Coverage_validate( table + Coverage, valid, -1 );
949 otv_ClassDef_validate( table + BacktrackClassDef, valid );
950 otv_ClassDef_validate( table + InputClassDef, valid );
951 otv_ClassDef_validate( table + LookaheadClassDef, valid );
953 OTV_LIMIT_CHECK( ChainClassSetCount * 2 );
955 valid->nesting_level++;
956 func = valid->func[valid->nesting_level];
957 valid->extra1 = valid->lookup_count;
959 for ( ; ChainClassSetCount > 0; ChainClassSetCount-- )
961 FT_UInt offset = FT_NEXT_USHORT( p );
964 if ( offset )
965 func( table + offset, valid );
968 valid->nesting_level--;
970 OTV_EXIT;
974 /* uses valid->lookup_count */
976 FT_LOCAL_DEF( void )
977 otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table,
978 OTV_Validator valid )
980 FT_Bytes p = table;
981 FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount;
982 FT_UInt count1, count2;
985 OTV_ENTER;
987 p += 2; /* skip Format */
989 OTV_LIMIT_CHECK( 2 );
990 BacktrackGlyphCount = FT_NEXT_USHORT( p );
992 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
994 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
996 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
997 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
999 InputGlyphCount = FT_NEXT_USHORT( p );
1001 OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount ));
1003 OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
1005 for ( count1 = InputGlyphCount; count1 > 0; count1-- )
1006 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
1008 LookaheadGlyphCount = FT_NEXT_USHORT( p );
1010 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
1012 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
1014 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
1015 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
1017 count2 = FT_NEXT_USHORT( p );
1019 OTV_TRACE(( " (Count = %d)\n", count2 ));
1021 OTV_LIMIT_CHECK( count2 * 4 );
1023 for ( ; count2 > 0; count2-- )
1025 if ( FT_NEXT_USHORT( p ) >= InputGlyphCount )
1026 FT_INVALID_DATA;
1028 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
1029 FT_INVALID_DATA;
1032 OTV_EXIT;
1036 FT_LOCAL_DEF( FT_UInt )
1037 otv_GSUBGPOS_get_Lookup_count( FT_Bytes table )
1039 FT_Bytes p = table + 8;
1042 return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) );
1046 FT_LOCAL_DEF( FT_UInt )
1047 otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table )
1049 FT_Bytes p, lookup;
1050 FT_UInt count;
1053 if ( !table )
1054 return 0;
1056 /* LookupList */
1057 p = table + 8;
1058 table += FT_NEXT_USHORT( p );
1060 /* LookupCount */
1061 p = table;
1062 count = FT_NEXT_USHORT( p );
1064 for ( ; count > 0; count-- )
1066 FT_Bytes oldp;
1069 /* Lookup */
1070 lookup = table + FT_NEXT_USHORT( p );
1072 oldp = p;
1074 /* LookupFlag */
1075 p = lookup + 2;
1076 if ( FT_NEXT_USHORT( p ) & 0xFF00U )
1077 return 1;
1079 p = oldp;
1082 return 0;
1086 /* END */