Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / thirdparty / freetype-2.3.12 / src / otvalid / otvgsub.c
blobed499d1e92dc2613b36b458eb80bc4a1371bc4aa
1 /***************************************************************************/
2 /* */
3 /* otvgsub.c */
4 /* */
5 /* OpenType GSUB table validation (body). */
6 /* */
7 /* Copyright 2004, 2005, 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 "otvalid.h"
20 #include "otvcommn.h"
23 /*************************************************************************/
24 /* */
25 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
26 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
27 /* messages during execution. */
28 /* */
29 #undef FT_COMPONENT
30 #define FT_COMPONENT trace_otvgsub
33 /*************************************************************************/
34 /*************************************************************************/
35 /***** *****/
36 /***** GSUB LOOKUP TYPE 1 *****/
37 /***** *****/
38 /*************************************************************************/
39 /*************************************************************************/
41 /* uses valid->glyph_count */
43 static void
44 otv_SingleSubst_validate( FT_Bytes table,
45 OTV_Validator valid )
47 FT_Bytes p = table;
48 FT_UInt SubstFormat;
51 OTV_NAME_ENTER( "SingleSubst" );
53 OTV_LIMIT_CHECK( 2 );
54 SubstFormat = FT_NEXT_USHORT( p );
56 OTV_TRACE(( " (format %d)\n", SubstFormat ));
58 switch ( SubstFormat )
60 case 1: /* SingleSubstFormat1 */
62 FT_Bytes Coverage;
63 FT_Int DeltaGlyphID;
64 FT_Long idx;
67 OTV_LIMIT_CHECK( 4 );
68 Coverage = table + FT_NEXT_USHORT( p );
69 DeltaGlyphID = FT_NEXT_SHORT( p );
71 otv_Coverage_validate( Coverage, valid, -1 );
73 idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
74 if ( idx < 0 )
75 FT_INVALID_DATA;
77 idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
78 if ( (FT_UInt)idx >= valid->glyph_count )
79 FT_INVALID_DATA;
81 break;
83 case 2: /* SingleSubstFormat2 */
85 FT_UInt Coverage, GlyphCount;
88 OTV_LIMIT_CHECK( 4 );
89 Coverage = FT_NEXT_USHORT( p );
90 GlyphCount = FT_NEXT_USHORT( p );
92 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
94 otv_Coverage_validate( table + Coverage, valid, GlyphCount );
96 OTV_LIMIT_CHECK( GlyphCount * 2 );
98 /* Substitute */
99 for ( ; GlyphCount > 0; GlyphCount-- )
100 if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
101 FT_INVALID_GLYPH_ID;
103 break;
105 default:
106 FT_INVALID_FORMAT;
109 OTV_EXIT;
113 /*************************************************************************/
114 /*************************************************************************/
115 /***** *****/
116 /***** GSUB LOOKUP TYPE 2 *****/
117 /***** *****/
118 /*************************************************************************/
119 /*************************************************************************/
121 /* sets valid->extra1 (glyph count) */
123 static void
124 otv_MultipleSubst_validate( FT_Bytes table,
125 OTV_Validator valid )
127 FT_Bytes p = table;
128 FT_UInt SubstFormat;
131 OTV_NAME_ENTER( "MultipleSubst" );
133 OTV_LIMIT_CHECK( 2 );
134 SubstFormat = FT_NEXT_USHORT( p );
136 OTV_TRACE(( " (format %d)\n", SubstFormat ));
138 switch ( SubstFormat )
140 case 1:
141 valid->extra1 = valid->glyph_count;
142 OTV_NEST2( MultipleSubstFormat1, Sequence );
143 OTV_RUN( table, valid );
144 break;
146 default:
147 FT_INVALID_FORMAT;
150 OTV_EXIT;
154 /*************************************************************************/
155 /*************************************************************************/
156 /***** *****/
157 /***** GSUB LOOKUP TYPE 3 *****/
158 /***** *****/
159 /*************************************************************************/
160 /*************************************************************************/
162 /* sets valid->extra1 (glyph count) */
164 static void
165 otv_AlternateSubst_validate( FT_Bytes table,
166 OTV_Validator valid )
168 FT_Bytes p = table;
169 FT_UInt SubstFormat;
172 OTV_NAME_ENTER( "AlternateSubst" );
174 OTV_LIMIT_CHECK( 2 );
175 SubstFormat = FT_NEXT_USHORT( p );
177 OTV_TRACE(( " (format %d)\n", SubstFormat ));
179 switch ( SubstFormat )
181 case 1:
182 valid->extra1 = valid->glyph_count;
183 OTV_NEST2( AlternateSubstFormat1, AlternateSet );
184 OTV_RUN( table, valid );
185 break;
187 default:
188 FT_INVALID_FORMAT;
191 OTV_EXIT;
195 /*************************************************************************/
196 /*************************************************************************/
197 /***** *****/
198 /***** GSUB LOOKUP TYPE 4 *****/
199 /***** *****/
200 /*************************************************************************/
201 /*************************************************************************/
203 #define LigatureFunc otv_Ligature_validate
205 /* uses valid->glyph_count */
207 static void
208 otv_Ligature_validate( FT_Bytes table,
209 OTV_Validator valid )
211 FT_Bytes p = table;
212 FT_UInt LigatureGlyph, CompCount;
215 OTV_ENTER;
217 OTV_LIMIT_CHECK( 4 );
218 LigatureGlyph = FT_NEXT_USHORT( p );
219 if ( LigatureGlyph >= valid->glyph_count )
220 FT_INVALID_DATA;
222 CompCount = FT_NEXT_USHORT( p );
224 OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
226 if ( CompCount == 0 )
227 FT_INVALID_DATA;
229 CompCount--;
231 OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */
233 /* no need to check the Component glyph indices */
235 OTV_EXIT;
239 static void
240 otv_LigatureSubst_validate( FT_Bytes table,
241 OTV_Validator valid )
243 FT_Bytes p = table;
244 FT_UInt SubstFormat;
247 OTV_NAME_ENTER( "LigatureSubst" );
249 OTV_LIMIT_CHECK( 2 );
250 SubstFormat = FT_NEXT_USHORT( p );
252 OTV_TRACE(( " (format %d)\n", SubstFormat ));
254 switch ( SubstFormat )
256 case 1:
257 OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
258 OTV_RUN( table, valid );
259 break;
261 default:
262 FT_INVALID_FORMAT;
265 OTV_EXIT;
269 /*************************************************************************/
270 /*************************************************************************/
271 /***** *****/
272 /***** GSUB LOOKUP TYPE 5 *****/
273 /***** *****/
274 /*************************************************************************/
275 /*************************************************************************/
277 /* sets valid->extra1 (lookup count) */
279 static void
280 otv_ContextSubst_validate( FT_Bytes table,
281 OTV_Validator valid )
283 FT_Bytes p = table;
284 FT_UInt SubstFormat;
287 OTV_NAME_ENTER( "ContextSubst" );
289 OTV_LIMIT_CHECK( 2 );
290 SubstFormat = FT_NEXT_USHORT( p );
292 OTV_TRACE(( " (format %d)\n", SubstFormat ));
294 switch ( SubstFormat )
296 case 1:
297 /* no need to check glyph indices/classes used as input for these */
298 /* context rules since even invalid glyph indices/classes return */
299 /* meaningful results */
301 valid->extra1 = valid->lookup_count;
302 OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
303 OTV_RUN( table, valid );
304 break;
306 case 2:
307 /* no need to check glyph indices/classes used as input for these */
308 /* context rules since even invalid glyph indices/classes return */
309 /* meaningful results */
311 OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
312 OTV_RUN( table, valid );
313 break;
315 case 3:
316 OTV_NEST1( ContextSubstFormat3 );
317 OTV_RUN( table, valid );
318 break;
320 default:
321 FT_INVALID_FORMAT;
324 OTV_EXIT;
328 /*************************************************************************/
329 /*************************************************************************/
330 /***** *****/
331 /***** GSUB LOOKUP TYPE 6 *****/
332 /***** *****/
333 /*************************************************************************/
334 /*************************************************************************/
336 /* sets valid->extra1 (lookup count) */
338 static void
339 otv_ChainContextSubst_validate( FT_Bytes table,
340 OTV_Validator valid )
342 FT_Bytes p = table;
343 FT_UInt SubstFormat;
346 OTV_NAME_ENTER( "ChainContextSubst" );
348 OTV_LIMIT_CHECK( 2 );
349 SubstFormat = FT_NEXT_USHORT( p );
351 OTV_TRACE(( " (format %d)\n", SubstFormat ));
353 switch ( SubstFormat )
355 case 1:
356 /* no need to check glyph indices/classes used as input for these */
357 /* context rules since even invalid glyph indices/classes return */
358 /* meaningful results */
360 valid->extra1 = valid->lookup_count;
361 OTV_NEST3( ChainContextSubstFormat1,
362 ChainSubRuleSet, ChainSubRule );
363 OTV_RUN( table, valid );
364 break;
366 case 2:
367 /* no need to check glyph indices/classes used as input for these */
368 /* context rules since even invalid glyph indices/classes return */
369 /* meaningful results */
371 OTV_NEST3( ChainContextSubstFormat2,
372 ChainSubClassSet, ChainSubClassRule );
373 OTV_RUN( table, valid );
374 break;
376 case 3:
377 OTV_NEST1( ChainContextSubstFormat3 );
378 OTV_RUN( table, valid );
379 break;
381 default:
382 FT_INVALID_FORMAT;
385 OTV_EXIT;
389 /*************************************************************************/
390 /*************************************************************************/
391 /***** *****/
392 /***** GSUB LOOKUP TYPE 7 *****/
393 /***** *****/
394 /*************************************************************************/
395 /*************************************************************************/
397 /* uses valid->type_funcs */
399 static void
400 otv_ExtensionSubst_validate( FT_Bytes table,
401 OTV_Validator valid )
403 FT_Bytes p = table;
404 FT_UInt SubstFormat;
407 OTV_NAME_ENTER( "ExtensionSubst" );
409 OTV_LIMIT_CHECK( 2 );
410 SubstFormat = FT_NEXT_USHORT( p );
412 OTV_TRACE(( " (format %d)\n", SubstFormat ));
414 switch ( SubstFormat )
416 case 1: /* ExtensionSubstFormat1 */
418 FT_UInt ExtensionLookupType;
419 FT_ULong ExtensionOffset;
420 OTV_Validate_Func validate;
423 OTV_LIMIT_CHECK( 6 );
424 ExtensionLookupType = FT_NEXT_USHORT( p );
425 ExtensionOffset = FT_NEXT_ULONG( p );
427 if ( ExtensionLookupType == 0 ||
428 ExtensionLookupType == 7 ||
429 ExtensionLookupType > 8 )
430 FT_INVALID_DATA;
432 validate = valid->type_funcs[ExtensionLookupType - 1];
433 validate( table + ExtensionOffset, valid );
435 break;
437 default:
438 FT_INVALID_FORMAT;
441 OTV_EXIT;
445 /*************************************************************************/
446 /*************************************************************************/
447 /***** *****/
448 /***** GSUB LOOKUP TYPE 8 *****/
449 /***** *****/
450 /*************************************************************************/
451 /*************************************************************************/
453 /* uses valid->glyph_count */
455 static void
456 otv_ReverseChainSingleSubst_validate( FT_Bytes table,
457 OTV_Validator valid )
459 FT_Bytes p = table, Coverage;
460 FT_UInt SubstFormat;
461 FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
464 OTV_NAME_ENTER( "ReverseChainSingleSubst" );
466 OTV_LIMIT_CHECK( 2 );
467 SubstFormat = FT_NEXT_USHORT( p );
469 OTV_TRACE(( " (format %d)\n", SubstFormat ));
471 switch ( SubstFormat )
473 case 1: /* ReverseChainSingleSubstFormat1 */
474 OTV_LIMIT_CHECK( 4 );
475 Coverage = table + FT_NEXT_USHORT( p );
476 BacktrackGlyphCount = FT_NEXT_USHORT( p );
478 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
480 otv_Coverage_validate( Coverage, valid, -1 );
482 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
484 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
485 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
487 LookaheadGlyphCount = FT_NEXT_USHORT( p );
489 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
491 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
493 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
494 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
496 GlyphCount = FT_NEXT_USHORT( p );
498 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
500 if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
501 FT_INVALID_DATA;
503 OTV_LIMIT_CHECK( GlyphCount * 2 );
505 /* Substitute */
506 for ( ; GlyphCount > 0; GlyphCount-- )
507 if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
508 FT_INVALID_DATA;
510 break;
512 default:
513 FT_INVALID_FORMAT;
516 OTV_EXIT;
520 static const OTV_Validate_Func otv_gsub_validate_funcs[8] =
522 otv_SingleSubst_validate,
523 otv_MultipleSubst_validate,
524 otv_AlternateSubst_validate,
525 otv_LigatureSubst_validate,
526 otv_ContextSubst_validate,
527 otv_ChainContextSubst_validate,
528 otv_ExtensionSubst_validate,
529 otv_ReverseChainSingleSubst_validate
533 /*************************************************************************/
534 /*************************************************************************/
535 /***** *****/
536 /***** GSUB TABLE *****/
537 /***** *****/
538 /*************************************************************************/
539 /*************************************************************************/
541 /* sets valid->type_count */
542 /* sets valid->type_funcs */
543 /* sets valid->glyph_count */
545 FT_LOCAL_DEF( void )
546 otv_GSUB_validate( FT_Bytes table,
547 FT_UInt glyph_count,
548 FT_Validator ftvalid )
550 OTV_ValidatorRec validrec;
551 OTV_Validator valid = &validrec;
552 FT_Bytes p = table;
553 FT_UInt ScriptList, FeatureList, LookupList;
556 valid->root = ftvalid;
558 FT_TRACE3(( "validating GSUB table\n" ));
559 OTV_INIT;
561 OTV_LIMIT_CHECK( 10 );
563 if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
564 FT_INVALID_FORMAT;
566 ScriptList = FT_NEXT_USHORT( p );
567 FeatureList = FT_NEXT_USHORT( p );
568 LookupList = FT_NEXT_USHORT( p );
570 valid->type_count = 8;
571 valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs;
572 valid->glyph_count = glyph_count;
574 otv_LookupList_validate( table + LookupList,
575 valid );
576 otv_FeatureList_validate( table + FeatureList, table + LookupList,
577 valid );
578 otv_ScriptList_validate( table + ScriptList, table + FeatureList,
579 valid );
581 FT_TRACE4(( "\n" ));
585 /* END */