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]
otvgpos.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* otvgpos.c */
4 /* */
5 /* OpenType GPOS table validation (body). */
6 /* */
7 /* Copyright 2002, 2004, 2005, 2006, 2007, 2008 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 #include "otvgpos.h"
22 
23 
24  /*************************************************************************/
25  /* */
26  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
27  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
28  /* messages during execution. */
29  /* */
30 #undef FT_COMPONENT
31 #define FT_COMPONENT trace_otvgpos
32 
33 
34  static void
35  otv_Anchor_validate( FT_Bytes table,
36  OTV_Validator valid );
37 
38  static void
39  otv_MarkArray_validate( FT_Bytes table,
40  OTV_Validator valid );
41 
42 
43  /*************************************************************************/
44  /*************************************************************************/
45  /***** *****/
46  /***** UTILITY FUNCTIONS *****/
47  /***** *****/
48  /*************************************************************************/
49  /*************************************************************************/
50 
51 #define BaseArrayFunc otv_x_sxy
52 #define LigatureAttachFunc otv_x_sxy
53 #define Mark2ArrayFunc otv_x_sxy
54 
55  /* uses valid->extra1 (counter) */
56  /* uses valid->extra2 (boolean to handle NULL anchor field) */
57 
58  static void
59  otv_x_sxy( FT_Bytes table,
60  OTV_Validator valid )
61  {
62  FT_Bytes p = table;
63  FT_UInt Count, count1, table_size;
64 
65 
66  OTV_ENTER;
67 
68  OTV_LIMIT_CHECK( 2 );
69 
70  Count = FT_NEXT_USHORT( p );
71 
72  OTV_TRACE(( " (Count = %d)\n", Count ));
73 
74  OTV_LIMIT_CHECK( Count * valid->extra1 * 2 );
75 
76  table_size = Count * valid->extra1 * 2 + 2;
77 
78  for ( ; Count > 0; Count-- )
79  for ( count1 = valid->extra1; count1 > 0; count1-- )
80  {
81  OTV_OPTIONAL_TABLE( anchor_offset );
82 
83 
84  OTV_OPTIONAL_OFFSET( anchor_offset );
85 
86  if ( valid->extra2 )
87  {
88  OTV_SIZE_CHECK( anchor_offset );
89  if ( anchor_offset )
90  otv_Anchor_validate( table + anchor_offset, valid );
91  }
92  else
93  otv_Anchor_validate( table + anchor_offset, valid );
94  }
95 
96  OTV_EXIT;
97  }
98 
99 
100 #define MarkBasePosFormat1Func otv_u_O_O_u_O_O
101 #define MarkLigPosFormat1Func otv_u_O_O_u_O_O
102 #define MarkMarkPosFormat1Func otv_u_O_O_u_O_O
103 
104  /* sets valid->extra1 (class count) */
105 
106  static void
107  otv_u_O_O_u_O_O( FT_Bytes table,
108  OTV_Validator valid )
109  {
110  FT_Bytes p = table;
111  FT_UInt Coverage1, Coverage2, ClassCount;
112  FT_UInt Array1, Array2;
114 
115 
116  OTV_ENTER;
117 
118  p += 2; /* skip PosFormat */
119 
120  OTV_LIMIT_CHECK( 10 );
121  Coverage1 = FT_NEXT_USHORT( p );
122  Coverage2 = FT_NEXT_USHORT( p );
123  ClassCount = FT_NEXT_USHORT( p );
124  Array1 = FT_NEXT_USHORT( p );
125  Array2 = FT_NEXT_USHORT( p );
126 
127  otv_Coverage_validate( table + Coverage1, valid, -1 );
128  otv_Coverage_validate( table + Coverage2, valid, -1 );
129 
130  otv_MarkArray_validate( table + Array1, valid );
131 
132  valid->nesting_level++;
133  func = valid->func[valid->nesting_level];
134  valid->extra1 = ClassCount;
135 
136  func( table + Array2, valid );
137 
138  valid->nesting_level--;
139 
140  OTV_EXIT;
141  }
142 
143 
144  /*************************************************************************/
145  /*************************************************************************/
146  /***** *****/
147  /***** VALUE RECORDS *****/
148  /***** *****/
149  /*************************************************************************/
150  /*************************************************************************/
151 
152  static FT_UInt
153  otv_value_length( FT_UInt format )
154  {
155  FT_UInt count;
156 
157 
158  count = ( ( format & 0xAA ) >> 1 ) + ( format & 0x55 );
159  count = ( ( count & 0xCC ) >> 2 ) + ( count & 0x33 );
160  count = ( ( count & 0xF0 ) >> 4 ) + ( count & 0x0F );
161 
162  return count * 2;
163  }
164 
165 
166  /* uses valid->extra3 (pointer to base table) */
167 
168  static void
169  otv_ValueRecord_validate( FT_Bytes table,
170  FT_UInt format,
171  OTV_Validator valid )
172  {
173  FT_Bytes p = table;
174  FT_UInt count;
175 
176 #ifdef FT_DEBUG_LEVEL_TRACE
177  FT_Int loop;
178  FT_ULong res = 0;
179 
180 
181  OTV_NAME_ENTER( "ValueRecord" );
182 
183  /* display `format' in dual representation */
184  for ( loop = 7; loop >= 0; loop-- )
185  {
186  res <<= 4;
187  res += ( format >> loop ) & 1;
188  }
189 
190  OTV_TRACE(( " (format 0b%08lx)\n", res ));
191 #endif
192 
193  if ( format >= 0x100 )
195 
196  for ( count = 4; count > 0; count-- )
197  {
198  if ( format & 1 )
199  {
200  /* XPlacement, YPlacement, XAdvance, YAdvance */
201  OTV_LIMIT_CHECK( 2 );
202  p += 2;
203  }
204 
205  format >>= 1;
206  }
207 
208  for ( count = 4; count > 0; count-- )
209  {
210  if ( format & 1 )
211  {
212  FT_PtrDist table_size;
213 
214  OTV_OPTIONAL_TABLE( device );
215 
216 
217  /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */
218  OTV_LIMIT_CHECK( 2 );
219  OTV_OPTIONAL_OFFSET( device );
220 
221  /* XXX: this value is usually too small, especially if the current */
222  /* ValueRecord is part of an array -- getting the correct table */
223  /* size is probably not worth the trouble */
224 
225  table_size = p - valid->extra3;
226 
227  OTV_SIZE_CHECK( device );
228  if ( device )
229  otv_Device_validate( valid->extra3 + device, valid );
230  }
231  format >>= 1;
232  }
233 
234  OTV_EXIT;
235  }
236 
237 
238  /*************************************************************************/
239  /*************************************************************************/
240  /***** *****/
241  /***** ANCHORS *****/
242  /***** *****/
243  /*************************************************************************/
244  /*************************************************************************/
245 
246  static void
247  otv_Anchor_validate( FT_Bytes table,
248  OTV_Validator valid )
249  {
250  FT_Bytes p = table;
251  FT_UInt AnchorFormat;
252 
253 
254  OTV_NAME_ENTER( "Anchor");
255 
256  OTV_LIMIT_CHECK( 6 );
257  AnchorFormat = FT_NEXT_USHORT( p );
258 
259  OTV_TRACE(( " (format %d)\n", AnchorFormat ));
260 
261  p += 4; /* skip XCoordinate and YCoordinate */
262 
263  switch ( AnchorFormat )
264  {
265  case 1:
266  break;
267 
268  case 2:
269  OTV_LIMIT_CHECK( 2 ); /* AnchorPoint */
270  break;
271 
272  case 3:
273  {
274  FT_UInt table_size;
275 
276  OTV_OPTIONAL_TABLE( XDeviceTable );
277  OTV_OPTIONAL_TABLE( YDeviceTable );
278 
279 
280  OTV_LIMIT_CHECK( 4 );
281  OTV_OPTIONAL_OFFSET( XDeviceTable );
282  OTV_OPTIONAL_OFFSET( YDeviceTable );
283 
284  table_size = 6 + 4;
285 
286  OTV_SIZE_CHECK( XDeviceTable );
287  if ( XDeviceTable )
288  otv_Device_validate( table + XDeviceTable, valid );
289 
290  OTV_SIZE_CHECK( YDeviceTable );
291  if ( YDeviceTable )
292  otv_Device_validate( table + YDeviceTable, valid );
293  }
294  break;
295 
296  default:
298  }
299 
300  OTV_EXIT;
301  }
302 
303 
304  /*************************************************************************/
305  /*************************************************************************/
306  /***** *****/
307  /***** MARK ARRAYS *****/
308  /***** *****/
309  /*************************************************************************/
310  /*************************************************************************/
311 
312  static void
313  otv_MarkArray_validate( FT_Bytes table,
314  OTV_Validator valid )
315  {
316  FT_Bytes p = table;
317  FT_UInt MarkCount;
318 
319 
320  OTV_NAME_ENTER( "MarkArray" );
321 
322  OTV_LIMIT_CHECK( 2 );
323  MarkCount = FT_NEXT_USHORT( p );
324 
325  OTV_TRACE(( " (MarkCount = %d)\n", MarkCount ));
326 
327  OTV_LIMIT_CHECK( MarkCount * 4 );
328 
329  /* MarkRecord */
330  for ( ; MarkCount > 0; MarkCount-- )
331  {
332  p += 2; /* skip Class */
333  /* MarkAnchor */
334  otv_Anchor_validate( table + FT_NEXT_USHORT( p ), valid );
335  }
336 
337  OTV_EXIT;
338  }
339 
340 
341  /*************************************************************************/
342  /*************************************************************************/
343  /***** *****/
344  /***** GPOS LOOKUP TYPE 1 *****/
345  /***** *****/
346  /*************************************************************************/
347  /*************************************************************************/
348 
349  /* sets valid->extra3 (pointer to base table) */
350 
351  static void
352  otv_SinglePos_validate( FT_Bytes table,
353  OTV_Validator valid )
354  {
355  FT_Bytes p = table;
356  FT_UInt PosFormat;
357 
358 
359  OTV_NAME_ENTER( "SinglePos" );
360 
361  OTV_LIMIT_CHECK( 2 );
362  PosFormat = FT_NEXT_USHORT( p );
363 
364  OTV_TRACE(( " (format %d)\n", PosFormat ));
365 
366  valid->extra3 = table;
367 
368  switch ( PosFormat )
369  {
370  case 1: /* SinglePosFormat1 */
371  {
372  FT_UInt Coverage, ValueFormat;
373 
374 
375  OTV_LIMIT_CHECK( 4 );
376  Coverage = FT_NEXT_USHORT( p );
377  ValueFormat = FT_NEXT_USHORT( p );
378 
379  otv_Coverage_validate( table + Coverage, valid, -1 );
380  otv_ValueRecord_validate( p, ValueFormat, valid ); /* Value */
381  }
382  break;
383 
384  case 2: /* SinglePosFormat2 */
385  {
386  FT_UInt Coverage, ValueFormat, ValueCount, len_value;
387 
388 
389  OTV_LIMIT_CHECK( 6 );
390  Coverage = FT_NEXT_USHORT( p );
391  ValueFormat = FT_NEXT_USHORT( p );
392  ValueCount = FT_NEXT_USHORT( p );
393 
394  OTV_TRACE(( " (ValueCount = %d)\n", ValueCount ));
395 
396  len_value = otv_value_length( ValueFormat );
397 
398  otv_Coverage_validate( table + Coverage, valid, ValueCount );
399 
400  OTV_LIMIT_CHECK( ValueCount * len_value );
401 
402  /* Value */
403  for ( ; ValueCount > 0; ValueCount-- )
404  {
405  otv_ValueRecord_validate( p, ValueFormat, valid );
406  p += len_value;
407  }
408  }
409  break;
410 
411  default:
413  }
414 
415  OTV_EXIT;
416  }
417 
418 
419  /*************************************************************************/
420  /*************************************************************************/
421  /***** *****/
422  /***** GPOS LOOKUP TYPE 2 *****/
423  /***** *****/
424  /*************************************************************************/
425  /*************************************************************************/
426 
427  static void
428  otv_PairSet_validate( FT_Bytes table,
429  FT_UInt format1,
430  FT_UInt format2,
431  OTV_Validator valid )
432  {
433  FT_Bytes p = table;
434  FT_UInt value_len1, value_len2, PairValueCount;
435 
436 
437  OTV_NAME_ENTER( "PairSet" );
438 
439  OTV_LIMIT_CHECK( 2 );
440  PairValueCount = FT_NEXT_USHORT( p );
441 
442  OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount ));
443 
444  value_len1 = otv_value_length( format1 );
445  value_len2 = otv_value_length( format2 );
446 
447  OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) );
448 
449  /* PairValueRecord */
450  for ( ; PairValueCount > 0; PairValueCount-- )
451  {
452  p += 2; /* skip SecondGlyph */
453 
454  if ( format1 )
455  otv_ValueRecord_validate( p, format1, valid ); /* Value1 */
456  p += value_len1;
457 
458  if ( format2 )
459  otv_ValueRecord_validate( p, format2, valid ); /* Value2 */
460  p += value_len2;
461  }
462 
463  OTV_EXIT;
464  }
465 
466 
467  /* sets valid->extra3 (pointer to base table) */
468 
469  static void
470  otv_PairPos_validate( FT_Bytes table,
471  OTV_Validator valid )
472  {
473  FT_Bytes p = table;
474  FT_UInt PosFormat;
475 
476 
477  OTV_NAME_ENTER( "PairPos" );
478 
479  OTV_LIMIT_CHECK( 2 );
480  PosFormat = FT_NEXT_USHORT( p );
481 
482  OTV_TRACE(( " (format %d)\n", PosFormat ));
483 
484  valid->extra3 = table;
485 
486  switch ( PosFormat )
487  {
488  case 1: /* PairPosFormat1 */
489  {
490  FT_UInt Coverage, ValueFormat1, ValueFormat2, PairSetCount;
491 
492 
493  OTV_LIMIT_CHECK( 8 );
494  Coverage = FT_NEXT_USHORT( p );
495  ValueFormat1 = FT_NEXT_USHORT( p );
496  ValueFormat2 = FT_NEXT_USHORT( p );
497  PairSetCount = FT_NEXT_USHORT( p );
498 
499  OTV_TRACE(( " (PairSetCount = %d)\n", PairSetCount ));
500 
501  otv_Coverage_validate( table + Coverage, valid, -1 );
502 
503  OTV_LIMIT_CHECK( PairSetCount * 2 );
504 
505  /* PairSetOffset */
506  for ( ; PairSetCount > 0; PairSetCount-- )
507  otv_PairSet_validate( table + FT_NEXT_USHORT( p ),
508  ValueFormat1, ValueFormat2, valid );
509  }
510  break;
511 
512  case 2: /* PairPosFormat2 */
513  {
514  FT_UInt Coverage, ValueFormat1, ValueFormat2, ClassDef1, ClassDef2;
515  FT_UInt ClassCount1, ClassCount2, len_value1, len_value2, count;
516 
517 
518  OTV_LIMIT_CHECK( 14 );
519  Coverage = FT_NEXT_USHORT( p );
520  ValueFormat1 = FT_NEXT_USHORT( p );
521  ValueFormat2 = FT_NEXT_USHORT( p );
522  ClassDef1 = FT_NEXT_USHORT( p );
523  ClassDef2 = FT_NEXT_USHORT( p );
524  ClassCount1 = FT_NEXT_USHORT( p );
525  ClassCount2 = FT_NEXT_USHORT( p );
526 
527  OTV_TRACE(( " (ClassCount1 = %d)\n", ClassCount1 ));
528  OTV_TRACE(( " (ClassCount2 = %d)\n", ClassCount2 ));
529 
530  len_value1 = otv_value_length( ValueFormat1 );
531  len_value2 = otv_value_length( ValueFormat2 );
532 
533  otv_Coverage_validate( table + Coverage, valid, -1 );
534  otv_ClassDef_validate( table + ClassDef1, valid );
535  otv_ClassDef_validate( table + ClassDef2, valid );
536 
537  OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 *
538  ( len_value1 + len_value2 ) );
539 
540  /* Class1Record */
541  for ( ; ClassCount1 > 0; ClassCount1-- )
542  {
543  /* Class2Record */
544  for ( count = ClassCount2; count > 0; count-- )
545  {
546  if ( ValueFormat1 )
547  /* Value1 */
548  otv_ValueRecord_validate( p, ValueFormat1, valid );
549  p += len_value1;
550 
551  if ( ValueFormat2 )
552  /* Value2 */
553  otv_ValueRecord_validate( p, ValueFormat2, valid );
554  p += len_value2;
555  }
556  }
557  }
558  break;
559 
560  default:
562  }
563 
564  OTV_EXIT;
565  }
566 
567 
568  /*************************************************************************/
569  /*************************************************************************/
570  /***** *****/
571  /***** GPOS LOOKUP TYPE 3 *****/
572  /***** *****/
573  /*************************************************************************/
574  /*************************************************************************/
575 
576  static void
577  otv_CursivePos_validate( FT_Bytes table,
578  OTV_Validator valid )
579  {
580  FT_Bytes p = table;
581  FT_UInt PosFormat;
582 
583 
584  OTV_NAME_ENTER( "CursivePos" );
585 
586  OTV_LIMIT_CHECK( 2 );
587  PosFormat = FT_NEXT_USHORT( p );
588 
589  OTV_TRACE(( " (format %d)\n", PosFormat ));
590 
591  switch ( PosFormat )
592  {
593  case 1: /* CursivePosFormat1 */
594  {
595  FT_UInt table_size;
596  FT_UInt Coverage, EntryExitCount;
597 
598  OTV_OPTIONAL_TABLE( EntryAnchor );
599  OTV_OPTIONAL_TABLE( ExitAnchor );
600 
601 
602  OTV_LIMIT_CHECK( 4 );
603  Coverage = FT_NEXT_USHORT( p );
604  EntryExitCount = FT_NEXT_USHORT( p );
605 
606  OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount ));
607 
608  otv_Coverage_validate( table + Coverage, valid, EntryExitCount );
609 
610  OTV_LIMIT_CHECK( EntryExitCount * 4 );
611 
612  table_size = EntryExitCount * 4 + 4;
613 
614  /* EntryExitRecord */
615  for ( ; EntryExitCount > 0; EntryExitCount-- )
616  {
617  OTV_OPTIONAL_OFFSET( EntryAnchor );
618  OTV_OPTIONAL_OFFSET( ExitAnchor );
619 
620  OTV_SIZE_CHECK( EntryAnchor );
621  if ( EntryAnchor )
622  otv_Anchor_validate( table + EntryAnchor, valid );
623 
624  OTV_SIZE_CHECK( ExitAnchor );
625  if ( ExitAnchor )
626  otv_Anchor_validate( table + ExitAnchor, valid );
627  }
628  }
629  break;
630 
631  default:
633  }
634 
635  OTV_EXIT;
636  }
637 
638 
639  /*************************************************************************/
640  /*************************************************************************/
641  /***** *****/
642  /***** GPOS LOOKUP TYPE 4 *****/
643  /***** *****/
644  /*************************************************************************/
645  /*************************************************************************/
646 
647  /* UNDOCUMENTED (in OpenType 1.5): */
648  /* BaseRecord tables can contain NULL pointers. */
649 
650  /* sets valid->extra2 (1) */
651 
652  static void
653  otv_MarkBasePos_validate( FT_Bytes table,
654  OTV_Validator valid )
655  {
656  FT_Bytes p = table;
657  FT_UInt PosFormat;
658 
659 
660  OTV_NAME_ENTER( "MarkBasePos" );
661 
662  OTV_LIMIT_CHECK( 2 );
663  PosFormat = FT_NEXT_USHORT( p );
664 
665  OTV_TRACE(( " (format %d)\n", PosFormat ));
666 
667  switch ( PosFormat )
668  {
669  case 1:
670  valid->extra2 = 1;
671  OTV_NEST2( MarkBasePosFormat1, BaseArray );
672  OTV_RUN( table, valid );
673  break;
674 
675  default:
677  }
678 
679  OTV_EXIT;
680  }
681 
682 
683  /*************************************************************************/
684  /*************************************************************************/
685  /***** *****/
686  /***** GPOS LOOKUP TYPE 5 *****/
687  /***** *****/
688  /*************************************************************************/
689  /*************************************************************************/
690 
691  /* sets valid->extra2 (1) */
692 
693  static void
694  otv_MarkLigPos_validate( FT_Bytes table,
695  OTV_Validator valid )
696  {
697  FT_Bytes p = table;
698  FT_UInt PosFormat;
699 
700 
701  OTV_NAME_ENTER( "MarkLigPos" );
702 
703  OTV_LIMIT_CHECK( 2 );
704  PosFormat = FT_NEXT_USHORT( p );
705 
706  OTV_TRACE(( " (format %d)\n", PosFormat ));
707 
708  switch ( PosFormat )
709  {
710  case 1:
711  valid->extra2 = 1;
712  OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach );
713  OTV_RUN( table, valid );
714  break;
715 
716  default:
718  }
719 
720  OTV_EXIT;
721  }
722 
723 
724  /*************************************************************************/
725  /*************************************************************************/
726  /***** *****/
727  /***** GPOS LOOKUP TYPE 6 *****/
728  /***** *****/
729  /*************************************************************************/
730  /*************************************************************************/
731 
732  /* sets valid->extra2 (0) */
733 
734  static void
735  otv_MarkMarkPos_validate( FT_Bytes table,
736  OTV_Validator valid )
737  {
738  FT_Bytes p = table;
739  FT_UInt PosFormat;
740 
741 
742  OTV_NAME_ENTER( "MarkMarkPos" );
743 
744  OTV_LIMIT_CHECK( 2 );
745  PosFormat = FT_NEXT_USHORT( p );
746 
747  OTV_TRACE(( " (format %d)\n", PosFormat ));
748 
749  switch ( PosFormat )
750  {
751  case 1:
752  valid->extra2 = 0;
753  OTV_NEST2( MarkMarkPosFormat1, Mark2Array );
754  OTV_RUN( table, valid );
755  break;
756 
757  default:
759  }
760 
761  OTV_EXIT;
762  }
763 
764 
765  /*************************************************************************/
766  /*************************************************************************/
767  /***** *****/
768  /***** GPOS LOOKUP TYPE 7 *****/
769  /***** *****/
770  /*************************************************************************/
771  /*************************************************************************/
772 
773  /* sets valid->extra1 (lookup count) */
774 
775  static void
776  otv_ContextPos_validate( FT_Bytes table,
777  OTV_Validator valid )
778  {
779  FT_Bytes p = table;
780  FT_UInt PosFormat;
781 
782 
783  OTV_NAME_ENTER( "ContextPos" );
784 
785  OTV_LIMIT_CHECK( 2 );
786  PosFormat = FT_NEXT_USHORT( p );
787 
788  OTV_TRACE(( " (format %d)\n", PosFormat ));
789 
790  switch ( PosFormat )
791  {
792  case 1:
793  /* no need to check glyph indices/classes used as input for these */
794  /* context rules since even invalid glyph indices/classes return */
795  /* meaningful results */
796 
797  valid->extra1 = valid->lookup_count;
798  OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule );
799  OTV_RUN( table, valid );
800  break;
801 
802  case 2:
803  /* no need to check glyph indices/classes used as input for these */
804  /* context rules since even invalid glyph indices/classes return */
805  /* meaningful results */
806 
807  OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule );
808  OTV_RUN( table, valid );
809  break;
810 
811  case 3:
812  OTV_NEST1( ContextPosFormat3 );
813  OTV_RUN( table, valid );
814  break;
815 
816  default:
818  }
819 
820  OTV_EXIT;
821  }
822 
823 
824  /*************************************************************************/
825  /*************************************************************************/
826  /***** *****/
827  /***** GPOS LOOKUP TYPE 8 *****/
828  /***** *****/
829  /*************************************************************************/
830  /*************************************************************************/
831 
832  /* sets valid->extra1 (lookup count) */
833 
834  static void
835  otv_ChainContextPos_validate( FT_Bytes table,
836  OTV_Validator valid )
837  {
838  FT_Bytes p = table;
839  FT_UInt PosFormat;
840 
841 
842  OTV_NAME_ENTER( "ChainContextPos" );
843 
844  OTV_LIMIT_CHECK( 2 );
845  PosFormat = FT_NEXT_USHORT( p );
846 
847  OTV_TRACE(( " (format %d)\n", PosFormat ));
848 
849  switch ( PosFormat )
850  {
851  case 1:
852  /* no need to check glyph indices/classes used as input for these */
853  /* context rules since even invalid glyph indices/classes return */
854  /* meaningful results */
855 
856  valid->extra1 = valid->lookup_count;
857  OTV_NEST3( ChainContextPosFormat1,
858  ChainPosRuleSet, ChainPosRule );
859  OTV_RUN( table, valid );
860  break;
861 
862  case 2:
863  /* no need to check glyph indices/classes used as input for these */
864  /* context rules since even invalid glyph indices/classes return */
865  /* meaningful results */
866 
867  OTV_NEST3( ChainContextPosFormat2,
868  ChainPosClassSet, ChainPosClassRule );
869  OTV_RUN( table, valid );
870  break;
871 
872  case 3:
873  OTV_NEST1( ChainContextPosFormat3 );
874  OTV_RUN( table, valid );
875  break;
876 
877  default:
879  }
880 
881  OTV_EXIT;
882  }
883 
884 
885  /*************************************************************************/
886  /*************************************************************************/
887  /***** *****/
888  /***** GPOS LOOKUP TYPE 9 *****/
889  /***** *****/
890  /*************************************************************************/
891  /*************************************************************************/
892 
893  /* uses valid->type_funcs */
894 
895  static void
896  otv_ExtensionPos_validate( FT_Bytes table,
897  OTV_Validator valid )
898  {
899  FT_Bytes p = table;
900  FT_UInt PosFormat;
901 
902 
903  OTV_NAME_ENTER( "ExtensionPos" );
904 
905  OTV_LIMIT_CHECK( 2 );
906  PosFormat = FT_NEXT_USHORT( p );
907 
908  OTV_TRACE(( " (format %d)\n", PosFormat ));
909 
910  switch ( PosFormat )
911  {
912  case 1: /* ExtensionPosFormat1 */
913  {
914  FT_UInt ExtensionLookupType;
915  FT_ULong ExtensionOffset;
916  OTV_Validate_Func validate;
917 
918 
919  OTV_LIMIT_CHECK( 6 );
920  ExtensionLookupType = FT_NEXT_USHORT( p );
921  ExtensionOffset = FT_NEXT_ULONG( p );
922 
923  if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 )
925 
926  validate = valid->type_funcs[ExtensionLookupType - 1];
927  validate( table + ExtensionOffset, valid );
928  }
929  break;
930 
931  default:
933  }
934 
935  OTV_EXIT;
936  }
937 
938 
939  static const OTV_Validate_Func otv_gpos_validate_funcs[9] =
940  {
941  otv_SinglePos_validate,
942  otv_PairPos_validate,
943  otv_CursivePos_validate,
944  otv_MarkBasePos_validate,
945  otv_MarkLigPos_validate,
946  otv_MarkMarkPos_validate,
947  otv_ContextPos_validate,
948  otv_ChainContextPos_validate,
949  otv_ExtensionPos_validate
950  };
951 
952 
953  /* sets valid->type_count */
954  /* sets valid->type_funcs */
955 
956  FT_LOCAL_DEF( void )
958  OTV_Validator valid )
959  {
960  valid->type_count = 9;
961  valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
962 
963  otv_Lookup_validate( table, valid );
964  }
965 
966 
967  /*************************************************************************/
968  /*************************************************************************/
969  /***** *****/
970  /***** GPOS TABLE *****/
971  /***** *****/
972  /*************************************************************************/
973  /*************************************************************************/
974 
975  /* sets valid->glyph_count */
976 
977  FT_LOCAL_DEF( void )
979  FT_UInt glyph_count,
980  FT_Validator ftvalid )
981  {
982  OTV_ValidatorRec validrec;
983  OTV_Validator valid = &validrec;
984  FT_Bytes p = table;
985  FT_UInt ScriptList, FeatureList, LookupList;
986 
987 
988  valid->root = ftvalid;
989 
990  FT_TRACE3(( "validating GPOS table\n" ));
991  OTV_INIT;
992 
993  OTV_LIMIT_CHECK( 10 );
994 
995  if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */
997 
998  ScriptList = FT_NEXT_USHORT( p );
999  FeatureList = FT_NEXT_USHORT( p );
1000  LookupList = FT_NEXT_USHORT( p );
1001 
1002  valid->type_count = 9;
1003  valid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
1004  valid->glyph_count = glyph_count;
1005 
1006  otv_LookupList_validate( table + LookupList,
1007  valid );
1008  otv_FeatureList_validate( table + FeatureList, table + LookupList,
1009  valid );
1010  otv_ScriptList_validate( table + ScriptList, table + FeatureList,
1011  valid );
1012 
1013  FT_TRACE4(( "\n" ));
1014  }
1015 
1016 
1017 /* END */
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:333
#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 OTV_OPTIONAL_TABLE(_table)
Definition: otvcommn.h:73
#define FT_INVALID_FORMAT
Definition: ftvalid.h:133
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
#define OTV_NEST1(x)
Definition: otvcommn.h:174
otv_GPOS_validate(FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid)
Definition: otvgpos.c:978
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
otv_ClassDef_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvcommn.c:221
otv_Lookup_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvcommn.c:346
otv_GPOS_subtable_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvgpos.c:957
#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
GLuint res
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
GLenum func
GLuint GLuint GLsizei count
#define OTV_SIZE_CHECK(_size)
Definition: otvcommn.h:88
otv_Device_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvcommn.c:307
#define FT_INVALID_DATA
Definition: ftvalid.h:141
#define OTV_NEST3(x, y, z)
Definition: otvcommn.h:187
GLenum GLsizei GLenum GLenum const GLvoid * table
#define OTV_OPTIONAL_OFFSET(_offset)
Definition: otvcommn.h:76
otv_FeatureList_validate(FT_Bytes table, FT_Bytes lookups, OTV_Validator valid)
Definition: otvcommn.c:463
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
otv_LookupList_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvcommn.c:383