Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
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, 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 /***************************************************************************/
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 valid->glyph_count */
42 
43  static void
44  otv_SingleSubst_validate( FT_Bytes table,
45  OTV_Validator valid )
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, valid, -1 );
72 
73  idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
74  if ( idx < 0 )
76 
77  idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
78  if ( (FT_UInt)idx >= valid->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, valid, GlyphCount );
95 
96  OTV_LIMIT_CHECK( GlyphCount * 2 );
97 
98  /* Substitute */
99  for ( ; GlyphCount > 0; GlyphCount-- )
100  if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
102  }
103  break;
104 
105  default:
107  }
108 
109  OTV_EXIT;
110  }
111 
112 
113  /*************************************************************************/
114  /*************************************************************************/
115  /***** *****/
116  /***** GSUB LOOKUP TYPE 2 *****/
117  /***** *****/
118  /*************************************************************************/
119  /*************************************************************************/
120 
121  /* sets valid->extra1 (glyph count) */
122 
123  static void
124  otv_MultipleSubst_validate( FT_Bytes table,
125  OTV_Validator valid )
126  {
127  FT_Bytes p = table;
128  FT_UInt SubstFormat;
129 
130 
131  OTV_NAME_ENTER( "MultipleSubst" );
132 
133  OTV_LIMIT_CHECK( 2 );
134  SubstFormat = FT_NEXT_USHORT( p );
135 
136  OTV_TRACE(( " (format %d)\n", SubstFormat ));
137 
138  switch ( SubstFormat )
139  {
140  case 1:
141  valid->extra1 = valid->glyph_count;
142  OTV_NEST2( MultipleSubstFormat1, Sequence );
143  OTV_RUN( table, valid );
144  break;
145 
146  default:
148  }
149 
150  OTV_EXIT;
151  }
152 
153 
154  /*************************************************************************/
155  /*************************************************************************/
156  /***** *****/
157  /***** GSUB LOOKUP TYPE 3 *****/
158  /***** *****/
159  /*************************************************************************/
160  /*************************************************************************/
161 
162  /* sets valid->extra1 (glyph count) */
163 
164  static void
165  otv_AlternateSubst_validate( FT_Bytes table,
166  OTV_Validator valid )
167  {
168  FT_Bytes p = table;
169  FT_UInt SubstFormat;
170 
171 
172  OTV_NAME_ENTER( "AlternateSubst" );
173 
174  OTV_LIMIT_CHECK( 2 );
175  SubstFormat = FT_NEXT_USHORT( p );
176 
177  OTV_TRACE(( " (format %d)\n", SubstFormat ));
178 
179  switch ( SubstFormat )
180  {
181  case 1:
182  valid->extra1 = valid->glyph_count;
183  OTV_NEST2( AlternateSubstFormat1, AlternateSet );
184  OTV_RUN( table, valid );
185  break;
186 
187  default:
189  }
190 
191  OTV_EXIT;
192  }
193 
194 
195  /*************************************************************************/
196  /*************************************************************************/
197  /***** *****/
198  /***** GSUB LOOKUP TYPE 4 *****/
199  /***** *****/
200  /*************************************************************************/
201  /*************************************************************************/
202 
203 #define LigatureFunc otv_Ligature_validate
204 
205  /* uses valid->glyph_count */
206 
207  static void
208  otv_Ligature_validate( FT_Bytes table,
209  OTV_Validator valid )
210  {
211  FT_Bytes p = table;
212  FT_UInt LigatureGlyph, CompCount;
213 
214 
215  OTV_ENTER;
216 
217  OTV_LIMIT_CHECK( 4 );
218  LigatureGlyph = FT_NEXT_USHORT( p );
219  if ( LigatureGlyph >= valid->glyph_count )
221 
222  CompCount = FT_NEXT_USHORT( p );
223 
224  OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
225 
226  if ( CompCount == 0 )
228 
229  CompCount--;
230 
231  OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */
232 
233  /* no need to check the Component glyph indices */
234 
235  OTV_EXIT;
236  }
237 
238 
239  static void
240  otv_LigatureSubst_validate( FT_Bytes table,
241  OTV_Validator valid )
242  {
243  FT_Bytes p = table;
244  FT_UInt SubstFormat;
245 
246 
247  OTV_NAME_ENTER( "LigatureSubst" );
248 
249  OTV_LIMIT_CHECK( 2 );
250  SubstFormat = FT_NEXT_USHORT( p );
251 
252  OTV_TRACE(( " (format %d)\n", SubstFormat ));
253 
254  switch ( SubstFormat )
255  {
256  case 1:
257  OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
258  OTV_RUN( table, valid );
259  break;
260 
261  default:
263  }
264 
265  OTV_EXIT;
266  }
267 
268 
269  /*************************************************************************/
270  /*************************************************************************/
271  /***** *****/
272  /***** GSUB LOOKUP TYPE 5 *****/
273  /***** *****/
274  /*************************************************************************/
275  /*************************************************************************/
276 
277  /* sets valid->extra1 (lookup count) */
278 
279  static void
280  otv_ContextSubst_validate( FT_Bytes table,
281  OTV_Validator valid )
282  {
283  FT_Bytes p = table;
284  FT_UInt SubstFormat;
285 
286 
287  OTV_NAME_ENTER( "ContextSubst" );
288 
289  OTV_LIMIT_CHECK( 2 );
290  SubstFormat = FT_NEXT_USHORT( p );
291 
292  OTV_TRACE(( " (format %d)\n", SubstFormat ));
293 
294  switch ( SubstFormat )
295  {
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 */
300 
301  valid->extra1 = valid->lookup_count;
302  OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
303  OTV_RUN( table, valid );
304  break;
305 
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 */
310 
311  OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
312  OTV_RUN( table, valid );
313  break;
314 
315  case 3:
316  OTV_NEST1( ContextSubstFormat3 );
317  OTV_RUN( table, valid );
318  break;
319 
320  default:
322  }
323 
324  OTV_EXIT;
325  }
326 
327 
328  /*************************************************************************/
329  /*************************************************************************/
330  /***** *****/
331  /***** GSUB LOOKUP TYPE 6 *****/
332  /***** *****/
333  /*************************************************************************/
334  /*************************************************************************/
335 
336  /* sets valid->extra1 (lookup count) */
337 
338  static void
339  otv_ChainContextSubst_validate( FT_Bytes table,
340  OTV_Validator valid )
341  {
342  FT_Bytes p = table;
343  FT_UInt SubstFormat;
344 
345 
346  OTV_NAME_ENTER( "ChainContextSubst" );
347 
348  OTV_LIMIT_CHECK( 2 );
349  SubstFormat = FT_NEXT_USHORT( p );
350 
351  OTV_TRACE(( " (format %d)\n", SubstFormat ));
352 
353  switch ( SubstFormat )
354  {
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 */
359 
360  valid->extra1 = valid->lookup_count;
361  OTV_NEST3( ChainContextSubstFormat1,
362  ChainSubRuleSet, ChainSubRule );
363  OTV_RUN( table, valid );
364  break;
365 
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 */
370 
371  OTV_NEST3( ChainContextSubstFormat2,
372  ChainSubClassSet, ChainSubClassRule );
373  OTV_RUN( table, valid );
374  break;
375 
376  case 3:
377  OTV_NEST1( ChainContextSubstFormat3 );
378  OTV_RUN( table, valid );
379  break;
380 
381  default:
383  }
384 
385  OTV_EXIT;
386  }
387 
388 
389  /*************************************************************************/
390  /*************************************************************************/
391  /***** *****/
392  /***** GSUB LOOKUP TYPE 7 *****/
393  /***** *****/
394  /*************************************************************************/
395  /*************************************************************************/
396 
397  /* uses valid->type_funcs */
398 
399  static void
400  otv_ExtensionSubst_validate( FT_Bytes table,
401  OTV_Validator valid )
402  {
403  FT_Bytes p = table;
404  FT_UInt SubstFormat;
405 
406 
407  OTV_NAME_ENTER( "ExtensionSubst" );
408 
409  OTV_LIMIT_CHECK( 2 );
410  SubstFormat = FT_NEXT_USHORT( p );
411 
412  OTV_TRACE(( " (format %d)\n", SubstFormat ));
413 
414  switch ( SubstFormat )
415  {
416  case 1: /* ExtensionSubstFormat1 */
417  {
418  FT_UInt ExtensionLookupType;
419  FT_ULong ExtensionOffset;
420  OTV_Validate_Func validate;
421 
422 
423  OTV_LIMIT_CHECK( 6 );
424  ExtensionLookupType = FT_NEXT_USHORT( p );
425  ExtensionOffset = FT_NEXT_ULONG( p );
426 
427  if ( ExtensionLookupType == 0 ||
428  ExtensionLookupType == 7 ||
429  ExtensionLookupType > 8 )
431 
432  validate = valid->type_funcs[ExtensionLookupType - 1];
433  validate( table + ExtensionOffset, valid );
434  }
435  break;
436 
437  default:
439  }
440 
441  OTV_EXIT;
442  }
443 
444 
445  /*************************************************************************/
446  /*************************************************************************/
447  /***** *****/
448  /***** GSUB LOOKUP TYPE 8 *****/
449  /***** *****/
450  /*************************************************************************/
451  /*************************************************************************/
452 
453  /* uses valid->glyph_count */
454 
455  static void
456  otv_ReverseChainSingleSubst_validate( FT_Bytes table,
457  OTV_Validator valid )
458  {
459  FT_Bytes p = table, Coverage;
460  FT_UInt SubstFormat;
461  FT_UInt BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
462 
463 
464  OTV_NAME_ENTER( "ReverseChainSingleSubst" );
465 
466  OTV_LIMIT_CHECK( 2 );
467  SubstFormat = FT_NEXT_USHORT( p );
468 
469  OTV_TRACE(( " (format %d)\n", SubstFormat ));
470 
471  switch ( SubstFormat )
472  {
473  case 1: /* ReverseChainSingleSubstFormat1 */
474  OTV_LIMIT_CHECK( 4 );
475  Coverage = table + FT_NEXT_USHORT( p );
476  BacktrackGlyphCount = FT_NEXT_USHORT( p );
477 
478  OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
479 
480  otv_Coverage_validate( Coverage, valid, -1 );
481 
482  OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
483 
484  for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
485  otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
486 
487  LookaheadGlyphCount = FT_NEXT_USHORT( p );
488 
489  OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
490 
491  OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
492 
493  for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
494  otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
495 
496  GlyphCount = FT_NEXT_USHORT( p );
497 
498  OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
499 
500  if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
502 
503  OTV_LIMIT_CHECK( GlyphCount * 2 );
504 
505  /* Substitute */
506  for ( ; GlyphCount > 0; GlyphCount-- )
507  if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
509 
510  break;
511 
512  default:
514  }
515 
516  OTV_EXIT;
517  }
518 
519 
520  static const OTV_Validate_Func otv_gsub_validate_funcs[8] =
521  {
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
530  };
531 
532 
533  /*************************************************************************/
534  /*************************************************************************/
535  /***** *****/
536  /***** GSUB TABLE *****/
537  /***** *****/
538  /*************************************************************************/
539  /*************************************************************************/
540 
541  /* sets valid->type_count */
542  /* sets valid->type_funcs */
543  /* sets valid->glyph_count */
544 
545  FT_LOCAL_DEF( void )
547  FT_UInt glyph_count,
548  FT_Validator ftvalid )
549  {
550  OTV_ValidatorRec validrec;
551  OTV_Validator valid = &validrec;
552  FT_Bytes p = table;
553  FT_UInt ScriptList, FeatureList, LookupList;
554 
555 
556  valid->root = ftvalid;
557 
558  FT_TRACE3(( "validating GSUB table\n" ));
559  OTV_INIT;
560 
561  OTV_LIMIT_CHECK( 10 );
562 
563  if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
565 
566  ScriptList = FT_NEXT_USHORT( p );
567  FeatureList = FT_NEXT_USHORT( p );
568  LookupList = FT_NEXT_USHORT( p );
569 
570  valid->type_count = 8;
571  valid->type_funcs = (OTV_Validate_Func*)otv_gsub_validate_funcs;
572  valid->glyph_count = glyph_count;
573 
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 );
580 
581  FT_TRACE4(( "\n" ));
582  }
583 
584 
585 /* END */
signed long FT_Long
Definition: fttypes.h:238
#define OTV_EXIT
Definition: otvcommn.h:198
unsigned long FT_ULong
Definition: fttypes.h:249
otv_ScriptList_validate(FT_Bytes table, FT_Bytes features, OTV_Validator valid)
Definition: otvcommn.c:584
GLfloat GLfloat p
#define OTV_TRACE(s)
Definition: otvcommn.h:200
#define FT_INVALID_FORMAT
Definition: ftvalid.h:133
otv_GSUB_validate(FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid)
Definition: otvgsub.c:546
signed int FT_Int
Definition: fttypes.h:216
#define OTV_INIT
Definition: otvcommn.h:195
#define OTV_ENTER
Definition: otvcommn.h:196
void(* OTV_Validate_Func)(FT_Bytes table, OTV_Validator valid)
Definition: otvcommn.h:41
#define OTV_NEST2(x, y)
Definition: otvcommn.h:180
otv_Coverage_get_last(FT_Bytes table)
Definition: otvcommn.c:146
#define OTV_NEST1(x)
Definition: otvcommn.h:174
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
FT_UInt idx
Definition: cffcmap.c:127
#define OTV_NAME_ENTER(name)
Definition: otvcommn.h:197
#define OTV_RUN
Definition: otvcommn.h:205
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
const FT_Byte * FT_Bytes
Definition: fttypes.h:161
#define OTV_LIMIT_CHECK(_count)
Definition: otvcommn.h:82
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
otv_Coverage_validate(FT_Bytes table, OTV_Validator valid, FT_Int expected_count)
Definition: otvcommn.c:41
typedefFT_BEGIN_HEADER struct OTV_ValidatorRec_ * OTV_Validator
Definition: otvcommn.h:39
unsigned int FT_UInt
Definition: fttypes.h:227
otv_Coverage_get_first(FT_Bytes table)
Definition: otvcommn.c:134
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
#define FT_INVALID_DATA
Definition: ftvalid.h:141
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:137
#define OTV_NEST3(x, y, z)
Definition: otvcommn.h:187
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
GLenum GLsizei GLenum GLenum const GLvoid * table
otv_FeatureList_validate(FT_Bytes table, FT_Bytes lookups, OTV_Validator valid)
Definition: otvcommn.c:463
otv_Coverage_get_count(FT_Bytes table)
Definition: otvcommn.c:175
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
otv_LookupList_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvcommn.c:383