ReactOS 0.4.15-dev-7924-g5949c20
otvgsub.c
Go to the documentation of this file.
1/***************************************************************************/
2/* */
3/* otvgsub.c */
4/* */
5/* OpenType GSUB table validation (body). */
6/* */
7/* Copyright 2004-2018 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/***************************************************************************/
17
18
19#include "otvalid.h"
20#include "otvcommn.h"
21
22
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
31
32
33 /*************************************************************************/
34 /*************************************************************************/
35 /***** *****/
36 /***** GSUB LOOKUP TYPE 1 *****/
37 /***** *****/
38 /*************************************************************************/
39 /*************************************************************************/
40
41 /* uses otvalid->glyph_count */
42
43 static void
45 OTV_Validator otvalid )
46 {
48 FT_UInt SubstFormat;
49
50
51 OTV_NAME_ENTER( "SingleSubst" );
52
53 OTV_LIMIT_CHECK( 2 );
54 SubstFormat = FT_NEXT_USHORT( p );
55
56 OTV_TRACE(( " (format %d)\n", SubstFormat ));
57
58 switch ( SubstFormat )
59 {
60 case 1: /* SingleSubstFormat1 */
61 {
62 FT_Bytes Coverage;
63 FT_Int DeltaGlyphID;
65
66
67 OTV_LIMIT_CHECK( 4 );
68 Coverage = table + FT_NEXT_USHORT( p );
69 DeltaGlyphID = FT_NEXT_SHORT( p );
70
71 otv_Coverage_validate( Coverage, otvalid, -1 );
72
73 idx = (FT_Long)otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
74 if ( idx < 0 )
76
77 idx = (FT_Long)otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
78 if ( (FT_UInt)idx >= otvalid->glyph_count )
80 }
81 break;
82
83 case 2: /* SingleSubstFormat2 */
84 {
85 FT_UInt Coverage, GlyphCount;
86
87
88 OTV_LIMIT_CHECK( 4 );
89 Coverage = FT_NEXT_USHORT( p );
90 GlyphCount = FT_NEXT_USHORT( p );
91
92 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
93
94 otv_Coverage_validate( table + Coverage,
95 otvalid,
96 (FT_Int)GlyphCount );
97
98 OTV_LIMIT_CHECK( GlyphCount * 2 );
99
100 /* Substitute */
101 for ( ; GlyphCount > 0; GlyphCount-- )
102 if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count )
104 }
105 break;
106
107 default:
109 }
110
111 OTV_EXIT;
112 }
113
114
115 /*************************************************************************/
116 /*************************************************************************/
117 /***** *****/
118 /***** GSUB LOOKUP TYPE 2 *****/
119 /***** *****/
120 /*************************************************************************/
121 /*************************************************************************/
122
123 /* sets otvalid->extra1 (glyph count) */
124
125 static void
127 OTV_Validator otvalid )
128 {
129 FT_Bytes p = table;
130 FT_UInt SubstFormat;
131
132
133 OTV_NAME_ENTER( "MultipleSubst" );
134
135 OTV_LIMIT_CHECK( 2 );
136 SubstFormat = FT_NEXT_USHORT( p );
137
138 OTV_TRACE(( " (format %d)\n", SubstFormat ));
139
140 switch ( SubstFormat )
141 {
142 case 1:
143 otvalid->extra1 = otvalid->glyph_count;
144 OTV_NEST2( MultipleSubstFormat1, Sequence );
145 OTV_RUN( table, otvalid );
146 break;
147
148 default:
150 }
151
152 OTV_EXIT;
153 }
154
155
156 /*************************************************************************/
157 /*************************************************************************/
158 /***** *****/
159 /***** GSUB LOOKUP TYPE 3 *****/
160 /***** *****/
161 /*************************************************************************/
162 /*************************************************************************/
163
164 /* sets otvalid->extra1 (glyph count) */
165
166 static void
168 OTV_Validator otvalid )
169 {
170 FT_Bytes p = table;
171 FT_UInt SubstFormat;
172
173
174 OTV_NAME_ENTER( "AlternateSubst" );
175
176 OTV_LIMIT_CHECK( 2 );
177 SubstFormat = FT_NEXT_USHORT( p );
178
179 OTV_TRACE(( " (format %d)\n", SubstFormat ));
180
181 switch ( SubstFormat )
182 {
183 case 1:
184 otvalid->extra1 = otvalid->glyph_count;
185 OTV_NEST2( AlternateSubstFormat1, AlternateSet );
186 OTV_RUN( table, otvalid );
187 break;
188
189 default:
191 }
192
193 OTV_EXIT;
194 }
195
196
197 /*************************************************************************/
198 /*************************************************************************/
199 /***** *****/
200 /***** GSUB LOOKUP TYPE 4 *****/
201 /***** *****/
202 /*************************************************************************/
203 /*************************************************************************/
204
205#define LigatureFunc otv_Ligature_validate
206
207 /* uses otvalid->glyph_count */
208
209 static void
211 OTV_Validator otvalid )
212 {
213 FT_Bytes p = table;
214 FT_UInt LigatureGlyph, CompCount;
215
216
217 OTV_ENTER;
218
219 OTV_LIMIT_CHECK( 4 );
221 if ( LigatureGlyph >= otvalid->glyph_count )
223
224 CompCount = FT_NEXT_USHORT( p );
225
226 OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
227
228 if ( CompCount == 0 )
230
231 CompCount--;
232
233 OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */
234
235 /* no need to check the Component glyph indices */
236
237 OTV_EXIT;
238 }
239
240
241 static void
243 OTV_Validator otvalid )
244 {
245 FT_Bytes p = table;
246 FT_UInt SubstFormat;
247
248
249 OTV_NAME_ENTER( "LigatureSubst" );
250
251 OTV_LIMIT_CHECK( 2 );
252 SubstFormat = FT_NEXT_USHORT( p );
253
254 OTV_TRACE(( " (format %d)\n", SubstFormat ));
255
256 switch ( SubstFormat )
257 {
258 case 1:
259 OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
260 OTV_RUN( table, otvalid );
261 break;
262
263 default:
265 }
266
267 OTV_EXIT;
268 }
269
270
271 /*************************************************************************/
272 /*************************************************************************/
273 /***** *****/
274 /***** GSUB LOOKUP TYPE 5 *****/
275 /***** *****/
276 /*************************************************************************/
277 /*************************************************************************/
278
279 /* sets otvalid->extra1 (lookup count) */
280
281 static void
283 OTV_Validator otvalid )
284 {
285 FT_Bytes p = table;
286 FT_UInt SubstFormat;
287
288
289 OTV_NAME_ENTER( "ContextSubst" );
290
291 OTV_LIMIT_CHECK( 2 );
292 SubstFormat = FT_NEXT_USHORT( p );
293
294 OTV_TRACE(( " (format %d)\n", SubstFormat ));
295
296 switch ( SubstFormat )
297 {
298 case 1:
299 /* no need to check glyph indices/classes used as input for these */
300 /* context rules since even invalid glyph indices/classes return */
301 /* meaningful results */
302
303 otvalid->extra1 = otvalid->lookup_count;
304 OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
305 OTV_RUN( table, otvalid );
306 break;
307
308 case 2:
309 /* no need to check glyph indices/classes used as input for these */
310 /* context rules since even invalid glyph indices/classes return */
311 /* meaningful results */
312
313 OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
314 OTV_RUN( table, otvalid );
315 break;
316
317 case 3:
318 OTV_NEST1( ContextSubstFormat3 );
319 OTV_RUN( table, otvalid );
320 break;
321
322 default:
324 }
325
326 OTV_EXIT;
327 }
328
329
330 /*************************************************************************/
331 /*************************************************************************/
332 /***** *****/
333 /***** GSUB LOOKUP TYPE 6 *****/
334 /***** *****/
335 /*************************************************************************/
336 /*************************************************************************/
337
338 /* sets otvalid->extra1 (lookup count) */
339
340 static void
342 OTV_Validator otvalid )
343 {
344 FT_Bytes p = table;
345 FT_UInt SubstFormat;
346
347
348 OTV_NAME_ENTER( "ChainContextSubst" );
349
350 OTV_LIMIT_CHECK( 2 );
351 SubstFormat = FT_NEXT_USHORT( p );
352
353 OTV_TRACE(( " (format %d)\n", SubstFormat ));
354
355 switch ( SubstFormat )
356 {
357 case 1:
358 /* no need to check glyph indices/classes used as input for these */
359 /* context rules since even invalid glyph indices/classes return */
360 /* meaningful results */
361
362 otvalid->extra1 = otvalid->lookup_count;
363 OTV_NEST3( ChainContextSubstFormat1,
364 ChainSubRuleSet, ChainSubRule );
365 OTV_RUN( table, otvalid );
366 break;
367
368 case 2:
369 /* no need to check glyph indices/classes used as input for these */
370 /* context rules since even invalid glyph indices/classes return */
371 /* meaningful results */
372
373 OTV_NEST3( ChainContextSubstFormat2,
374 ChainSubClassSet, ChainSubClassRule );
375 OTV_RUN( table, otvalid );
376 break;
377
378 case 3:
379 OTV_NEST1( ChainContextSubstFormat3 );
380 OTV_RUN( table, otvalid );
381 break;
382
383 default:
385 }
386
387 OTV_EXIT;
388 }
389
390
391 /*************************************************************************/
392 /*************************************************************************/
393 /***** *****/
394 /***** GSUB LOOKUP TYPE 7 *****/
395 /***** *****/
396 /*************************************************************************/
397 /*************************************************************************/
398
399 /* uses otvalid->type_funcs */
400
401 static void
403 OTV_Validator otvalid )
404 {
405 FT_Bytes p = table;
406 FT_UInt SubstFormat;
407
408
409 OTV_NAME_ENTER( "ExtensionSubst" );
410
411 OTV_LIMIT_CHECK( 2 );
412 SubstFormat = FT_NEXT_USHORT( p );
413
414 OTV_TRACE(( " (format %d)\n", SubstFormat ));
415
416 switch ( SubstFormat )
417 {
418 case 1: /* ExtensionSubstFormat1 */
419 {
420 FT_UInt ExtensionLookupType;
421 FT_ULong ExtensionOffset;
423
424
425 OTV_LIMIT_CHECK( 6 );
426 ExtensionLookupType = FT_NEXT_USHORT( p );
427 ExtensionOffset = FT_NEXT_ULONG( p );
428
429 if ( ExtensionLookupType == 0 ||
430 ExtensionLookupType == 7 ||
431 ExtensionLookupType > 8 )
433
434 validate = otvalid->type_funcs[ExtensionLookupType - 1];
435 validate( table + ExtensionOffset, otvalid );
436 }
437 break;
438
439 default:
441 }
442
443 OTV_EXIT;
444 }
445
446
447 /*************************************************************************/
448 /*************************************************************************/
449 /***** *****/
450 /***** GSUB LOOKUP TYPE 8 *****/
451 /***** *****/
452 /*************************************************************************/
453 /*************************************************************************/
454
455 /* uses otvalid->glyph_count */
456
457 static void
459 OTV_Validator otvalid )
460 {
461 FT_Bytes p = table, Coverage;
462 FT_UInt SubstFormat;
463 FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
464
465
466 OTV_NAME_ENTER( "ReverseChainSingleSubst" );
467
468 OTV_LIMIT_CHECK( 2 );
469 SubstFormat = FT_NEXT_USHORT( p );
470
471 OTV_TRACE(( " (format %d)\n", SubstFormat ));
472
473 switch ( SubstFormat )
474 {
475 case 1: /* ReverseChainSingleSubstFormat1 */
476 OTV_LIMIT_CHECK( 4 );
477 Coverage = table + FT_NEXT_USHORT( p );
478 BacktrackGlyphCount = FT_NEXT_USHORT( p );
479
480 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
481
482 otv_Coverage_validate( Coverage, otvalid, -1 );
483
484 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
485
486 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
487 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 );
488
489 LookaheadGlyphCount = FT_NEXT_USHORT( p );
490
491 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
492
493 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
494
495 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
496 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 );
497
498 GlyphCount = FT_NEXT_USHORT( p );
499
500 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
501
502 if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
504
505 OTV_LIMIT_CHECK( GlyphCount * 2 );
506
507 /* Substitute */
508 for ( ; GlyphCount > 0; GlyphCount-- )
509 if ( FT_NEXT_USHORT( p ) >= otvalid->glyph_count )
511
512 break;
513
514 default:
516 }
517
518 OTV_EXIT;
519 }
520
521
523 {
532 };
533
534
535 /*************************************************************************/
536 /*************************************************************************/
537 /***** *****/
538 /***** GSUB TABLE *****/
539 /***** *****/
540 /*************************************************************************/
541 /*************************************************************************/
542
543 /* sets otvalid->type_count */
544 /* sets otvalid->type_funcs */
545 /* sets otvalid->glyph_count */
546
547 FT_LOCAL_DEF( void )
549 FT_UInt glyph_count,
550 FT_Validator ftvalid )
551 {
552 OTV_ValidatorRec otvalidrec;
553 OTV_Validator otvalid = &otvalidrec;
554 FT_Bytes p = table;
557 FT_UInt ScriptList, FeatureList, LookupList;
558
559 OTV_OPTIONAL_TABLE32( featureVariations );
560
561
562 otvalid->root = ftvalid;
563
564 FT_TRACE3(( "validating GSUB table\n" ));
565 OTV_INIT;
566
567 OTV_LIMIT_CHECK( 4 );
568
569 if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */
571
572 version = FT_NEXT_USHORT( p ); /* minorVersion */
573
574 table_size = 10;
575 switch ( version )
576 {
577 case 0:
578 OTV_LIMIT_CHECK( 6 );
579 break;
580
581 case 1:
582 OTV_LIMIT_CHECK( 10 );
583 table_size += 4;
584 break;
585
586 default:
588 }
589
590 ScriptList = FT_NEXT_USHORT( p );
592 LookupList = FT_NEXT_USHORT( p );
593
594 otvalid->type_count = 8;
595 otvalid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs;
596 otvalid->glyph_count = glyph_count;
597
598 otv_LookupList_validate( table + LookupList,
599 otvalid );
601 otvalid );
603 otvalid );
604
605 if ( version > 0 )
606 {
607 OTV_OPTIONAL_OFFSET32( featureVariations );
608 OTV_SIZE_CHECK32( featureVariations );
609 if ( featureVariations )
610 OTV_TRACE(( " [omitting featureVariations validation]\n" )); /* XXX */
611 }
612
613 FT_TRACE4(( "\n" ));
614 }
615
616
617/* END */
unsigned int idx
Definition: utils.c:41
static const WCHAR version[]
Definition: asmname.c:66
static FRESULT validate(void *obj)
Definition: ff.c:2372
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
unsigned long FT_ULong
Definition: fttypes.h:253
signed long FT_Long
Definition: fttypes.h:242
unsigned short FT_UShort
Definition: fttypes.h:209
unsigned int FT_UInt
Definition: fttypes.h:231
const FT_Byte * FT_Bytes
Definition: fttypes.h:165
signed int FT_Int
Definition: fttypes.h:220
#define FT_INVALID_FORMAT
Definition: ftvalid.h:142
#define FT_INVALID_DATA
Definition: ftvalid.h:150
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:146
GLfloat GLfloat p
Definition: glext.h:8902
ROSDATA LIGATURE2 Ligature[]
Definition: kbda1.c:341
struct tagFeatureList FeatureList
@ LigatureGlyph
Definition: opentype.c:105
otv_ScriptList_validate(FT_Bytes table, FT_Bytes features, OTV_Validator otvalid)
Definition: otvcommn.c:594
otv_Coverage_get_last(FT_Bytes table)
Definition: otvcommn.c:146
otv_Coverage_validate(FT_Bytes table, OTV_Validator otvalid, FT_Int expected_count)
Definition: otvcommn.c:41
otv_Coverage_get_count(FT_Bytes table)
Definition: otvcommn.c:175
otv_FeatureList_validate(FT_Bytes table, FT_Bytes lookups, OTV_Validator otvalid)
Definition: otvcommn.c:473
otv_Coverage_get_first(FT_Bytes table)
Definition: otvcommn.c:134
otv_LookupList_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.c:393
#define OTV_TRACE(s)
Definition: otvcommn.h:230
typedefFT_BEGIN_HEADER struct OTV_ValidatorRec_ * OTV_Validator
Definition: otvcommn.h:39
void(* OTV_Validate_Func)(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.h:41
#define OTV_SIZE_CHECK32(_size)
Definition: otvcommn.h:119
#define OTV_RUN
Definition: otvcommn.h:235
#define OTV_OPTIONAL_TABLE32(_table)
Definition: otvcommn.h:76
#define OTV_INIT
Definition: otvcommn.h:225
#define OTV_NEST2(x, y)
Definition: otvcommn.h:210
#define OTV_EXIT
Definition: otvcommn.h:228
#define OTV_NAME_ENTER(name)
Definition: otvcommn.h:227
#define OTV_OPTIONAL_OFFSET32(_offset)
Definition: otvcommn.h:85
#define OTV_NEST1(x)
Definition: otvcommn.h:204
#define OTV_LIMIT_CHECK(_count)
Definition: otvcommn.h:91
#define OTV_ENTER
Definition: otvcommn.h:226
#define OTV_NEST3(x, y, z)
Definition: otvcommn.h:217
static void otv_AlternateSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:167
static void otv_ExtensionSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:402
static void otv_ContextSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:282
otv_GSUB_validate(FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid)
Definition: otvgsub.c:548
static void otv_ReverseChainSingleSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:458
static const OTV_Validate_Func otv_gsub_validate_funcs[8]
Definition: otvgsub.c:522
static void otv_MultipleSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:126
static void otv_Ligature_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:210
static void otv_SingleSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:44
static void otv_ChainContextSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:341
static void otv_LigatureSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:242
LOCAL int table_size
Definition: write.c:65