ReactOS  0.4.15-dev-3294-ge98684e
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  {
47  FT_Bytes p = table;
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;
64  FT_Long idx;
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 */
otv_Coverage_validate(FT_Bytes table, OTV_Validator otvalid, FT_Int expected_count)
Definition: otvcommn.c:41
static void otv_LigatureSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:242
signed long FT_Long
Definition: fttypes.h:242
#define OTV_EXIT
Definition: otvcommn.h:228
unsigned long FT_ULong
Definition: fttypes.h:253
static void otv_Ligature_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:210
#define OTV_TRACE(s)
Definition: otvcommn.h:230
#define FT_INVALID_FORMAT
Definition: ftvalid.h:142
otv_GSUB_validate(FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid)
Definition: otvgsub.c:548
signed int FT_Int
Definition: fttypes.h:220
otv_ScriptList_validate(FT_Bytes table, FT_Bytes features, OTV_Validator otvalid)
Definition: otvcommn.c:594
#define OTV_INIT
Definition: otvcommn.h:225
#define OTV_ENTER
Definition: otvcommn.h:226
static void otv_ReverseChainSingleSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:458
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
#define OTV_OPTIONAL_OFFSET32(_offset)
Definition: otvcommn.h:85
#define OTV_NEST2(x, y)
Definition: otvcommn.h:210
struct tagFeatureList FeatureList
otv_Coverage_get_last(FT_Bytes table)
Definition: otvcommn.c:146
void(* OTV_Validate_Func)(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.h:41
#define OTV_NEST1(x)
Definition: otvcommn.h:204
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
unsigned int idx
Definition: utils.c:41
static const WCHAR version[]
Definition: asmname.c:66
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
static void otv_AlternateSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:167
otv_LookupList_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.c:393
static void otv_SingleSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:44
static const OTV_Validate_Func otv_gsub_validate_funcs[8]
Definition: otvgsub.c:522
#define OTV_NAME_ENTER(name)
Definition: otvcommn.h:227
#define OTV_RUN
Definition: otvcommn.h:235
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
static void otv_ChainContextSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:341
#define OTV_OPTIONAL_TABLE32(_table)
Definition: otvcommn.h:76
const FT_Byte * FT_Bytes
Definition: fttypes.h:165
static void otv_ExtensionSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:402
#define OTV_SIZE_CHECK32(_size)
Definition: otvcommn.h:119
#define OTV_LIMIT_CHECK(_count)
Definition: otvcommn.h:91
ROSDATA LIGATURE2 Ligature[]
Definition: kbda1.c:343
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
typedefFT_BEGIN_HEADER struct OTV_ValidatorRec_ * OTV_Validator
Definition: otvcommn.h:39
otv_FeatureList_validate(FT_Bytes table, FT_Bytes lookups, OTV_Validator otvalid)
Definition: otvcommn.c:473
unsigned int FT_UInt
Definition: fttypes.h:231
otv_Coverage_get_first(FT_Bytes table)
Definition: otvcommn.c:134
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
static void otv_MultipleSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:126
static FRESULT validate(void *obj)
Definition: ff.c:2372
#define FT_INVALID_DATA
Definition: ftvalid.h:150
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:146
#define OTV_NEST3(x, y, z)
Definition: otvcommn.h:217
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
GLfloat GLfloat p
Definition: glext.h:8902
unsigned short FT_UShort
Definition: fttypes.h:209
otv_Coverage_get_count(FT_Bytes table)
Definition: otvcommn.c:175
static void otv_ContextSubst_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgsub.c:282
LOCAL int table_size
Definition: write.c:65