ReactOS  0.4.14-dev-854-gb9426a3
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-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 #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
36  OTV_Validator valid );
37 
38  static void
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
60  OTV_Validator otvalid )
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 * otvalid->extra1 * 2 );
75 
76  table_size = Count * otvalid->extra1 * 2 + 2;
77 
78  for ( ; Count > 0; Count-- )
79  for ( count1 = otvalid->extra1; count1 > 0; count1-- )
80  {
81  OTV_OPTIONAL_TABLE( anchor_offset );
82 
83 
84  OTV_OPTIONAL_OFFSET( anchor_offset );
85 
86  if ( otvalid->extra2 )
87  {
88  OTV_SIZE_CHECK( anchor_offset );
89  if ( anchor_offset )
90  otv_Anchor_validate( table + anchor_offset, otvalid );
91  }
92  else
93  otv_Anchor_validate( table + anchor_offset, otvalid );
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 otvalid->extra1 (class count) */
105 
106  static void
108  OTV_Validator otvalid )
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, otvalid, -1 );
128  otv_Coverage_validate( table + Coverage2, otvalid, -1 );
129 
130  otv_MarkArray_validate( table + Array1, otvalid );
131 
132  otvalid->nesting_level++;
133  func = otvalid->func[otvalid->nesting_level];
134  otvalid->extra1 = ClassCount;
135 
136  func( table + Array2, otvalid );
137 
138  otvalid->nesting_level--;
139 
140  OTV_EXIT;
141  }
142 
143 
144  /*************************************************************************/
145  /*************************************************************************/
146  /***** *****/
147  /***** VALUE RECORDS *****/
148  /***** *****/
149  /*************************************************************************/
150  /*************************************************************************/
151 
152  static FT_UInt
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 otvalid->extra3 (pointer to base table) */
167 
168  static void
170  FT_UInt format,
171  OTV_Validator otvalid )
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  {
213 
215 
216 
217  /* XPlaDevice, YPlaDevice, XAdvDevice, YAdvDevice */
218  OTV_LIMIT_CHECK( 2 );
220 
221  table_size = p - otvalid->extra3;
222 
224  if ( device )
225  otv_Device_validate( otvalid->extra3 + device, otvalid );
226  }
227  format >>= 1;
228  }
229 
230  OTV_EXIT;
231  }
232 
233 
234  /*************************************************************************/
235  /*************************************************************************/
236  /***** *****/
237  /***** ANCHORS *****/
238  /***** *****/
239  /*************************************************************************/
240  /*************************************************************************/
241 
242  static void
244  OTV_Validator otvalid )
245  {
246  FT_Bytes p = table;
247  FT_UInt AnchorFormat;
248 
249 
250  OTV_NAME_ENTER( "Anchor");
251 
252  OTV_LIMIT_CHECK( 6 );
253  AnchorFormat = FT_NEXT_USHORT( p );
254 
255  OTV_TRACE(( " (format %d)\n", AnchorFormat ));
256 
257  p += 4; /* skip XCoordinate and YCoordinate */
258 
259  switch ( AnchorFormat )
260  {
261  case 1:
262  break;
263 
264  case 2:
265  OTV_LIMIT_CHECK( 2 ); /* AnchorPoint */
266  break;
267 
268  case 3:
269  {
271 
272  OTV_OPTIONAL_TABLE( XDeviceTable );
273  OTV_OPTIONAL_TABLE( YDeviceTable );
274 
275 
276  OTV_LIMIT_CHECK( 4 );
277  OTV_OPTIONAL_OFFSET( XDeviceTable );
278  OTV_OPTIONAL_OFFSET( YDeviceTable );
279 
280  table_size = 6 + 4;
281 
282  OTV_SIZE_CHECK( XDeviceTable );
283  if ( XDeviceTable )
284  otv_Device_validate( table + XDeviceTable, otvalid );
285 
286  OTV_SIZE_CHECK( YDeviceTable );
287  if ( YDeviceTable )
288  otv_Device_validate( table + YDeviceTable, otvalid );
289  }
290  break;
291 
292  default:
294  }
295 
296  OTV_EXIT;
297  }
298 
299 
300  /*************************************************************************/
301  /*************************************************************************/
302  /***** *****/
303  /***** MARK ARRAYS *****/
304  /***** *****/
305  /*************************************************************************/
306  /*************************************************************************/
307 
308  static void
310  OTV_Validator otvalid )
311  {
312  FT_Bytes p = table;
313  FT_UInt MarkCount;
314 
315 
316  OTV_NAME_ENTER( "MarkArray" );
317 
318  OTV_LIMIT_CHECK( 2 );
319  MarkCount = FT_NEXT_USHORT( p );
320 
321  OTV_TRACE(( " (MarkCount = %d)\n", MarkCount ));
322 
323  OTV_LIMIT_CHECK( MarkCount * 4 );
324 
325  /* MarkRecord */
326  for ( ; MarkCount > 0; MarkCount-- )
327  {
328  p += 2; /* skip Class */
329  /* MarkAnchor */
330  otv_Anchor_validate( table + FT_NEXT_USHORT( p ), otvalid );
331  }
332 
333  OTV_EXIT;
334  }
335 
336 
337  /*************************************************************************/
338  /*************************************************************************/
339  /***** *****/
340  /***** GPOS LOOKUP TYPE 1 *****/
341  /***** *****/
342  /*************************************************************************/
343  /*************************************************************************/
344 
345  /* sets otvalid->extra3 (pointer to base table) */
346 
347  static void
349  OTV_Validator otvalid )
350  {
351  FT_Bytes p = table;
352  FT_UInt PosFormat;
353 
354 
355  OTV_NAME_ENTER( "SinglePos" );
356 
357  OTV_LIMIT_CHECK( 2 );
358  PosFormat = FT_NEXT_USHORT( p );
359 
360  OTV_TRACE(( " (format %d)\n", PosFormat ));
361 
362  otvalid->extra3 = table;
363 
364  switch ( PosFormat )
365  {
366  case 1: /* SinglePosFormat1 */
367  {
368  FT_UInt Coverage, ValueFormat;
369 
370 
371  OTV_LIMIT_CHECK( 4 );
372  Coverage = FT_NEXT_USHORT( p );
373  ValueFormat = FT_NEXT_USHORT( p );
374 
375  otv_Coverage_validate( table + Coverage, otvalid, -1 );
376  otv_ValueRecord_validate( p, ValueFormat, otvalid ); /* Value */
377  }
378  break;
379 
380  case 2: /* SinglePosFormat2 */
381  {
382  FT_UInt Coverage, ValueFormat, ValueCount, len_value;
383 
384 
385  OTV_LIMIT_CHECK( 6 );
386  Coverage = FT_NEXT_USHORT( p );
387  ValueFormat = FT_NEXT_USHORT( p );
388  ValueCount = FT_NEXT_USHORT( p );
389 
390  OTV_TRACE(( " (ValueCount = %d)\n", ValueCount ));
391 
392  len_value = otv_value_length( ValueFormat );
393 
394  otv_Coverage_validate( table + Coverage,
395  otvalid,
396  (FT_Int)ValueCount );
397 
398  OTV_LIMIT_CHECK( ValueCount * len_value );
399 
400  /* Value */
401  for ( ; ValueCount > 0; ValueCount-- )
402  {
403  otv_ValueRecord_validate( p, ValueFormat, otvalid );
404  p += len_value;
405  }
406  }
407  break;
408 
409  default:
411  }
412 
413  OTV_EXIT;
414  }
415 
416 
417  /*************************************************************************/
418  /*************************************************************************/
419  /***** *****/
420  /***** GPOS LOOKUP TYPE 2 *****/
421  /***** *****/
422  /*************************************************************************/
423  /*************************************************************************/
424 
425  /* sets otvalid->extra3 (pointer to base table) */
426 
427  static void
429  FT_UInt format1,
430  FT_UInt format2,
431  OTV_Validator otvalid )
432  {
433  FT_Bytes p = table;
434  FT_UInt value_len1, value_len2, PairValueCount;
435 
436 
437  OTV_NAME_ENTER( "PairSet" );
438 
439  otvalid->extra3 = table;
440 
441  OTV_LIMIT_CHECK( 2 );
442  PairValueCount = FT_NEXT_USHORT( p );
443 
444  OTV_TRACE(( " (PairValueCount = %d)\n", PairValueCount ));
445 
446  value_len1 = otv_value_length( format1 );
447  value_len2 = otv_value_length( format2 );
448 
449  OTV_LIMIT_CHECK( PairValueCount * ( value_len1 + value_len2 + 2 ) );
450 
451  /* PairValueRecord */
452  for ( ; PairValueCount > 0; PairValueCount-- )
453  {
454  p += 2; /* skip SecondGlyph */
455 
456  if ( format1 )
457  otv_ValueRecord_validate( p, format1, otvalid ); /* Value1 */
458  p += value_len1;
459 
460  if ( format2 )
461  otv_ValueRecord_validate( p, format2, otvalid ); /* Value2 */
462  p += value_len2;
463  }
464 
465  OTV_EXIT;
466  }
467 
468 
469  /* sets otvalid->extra3 (pointer to base table) */
470 
471  static void
473  OTV_Validator otvalid )
474  {
475  FT_Bytes p = table;
476  FT_UInt PosFormat;
477 
478 
479  OTV_NAME_ENTER( "PairPos" );
480 
481  OTV_LIMIT_CHECK( 2 );
482  PosFormat = FT_NEXT_USHORT( p );
483 
484  OTV_TRACE(( " (format %d)\n", PosFormat ));
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, otvalid, -1 );
502 
503  OTV_LIMIT_CHECK( PairSetCount * 2 );
504 
505  /* PairSetOffset */
506  for ( ; PairSetCount > 0; PairSetCount-- )
508  ValueFormat1, ValueFormat2, otvalid );
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, otvalid, -1 );
534  otv_ClassDef_validate( table + ClassDef1, otvalid );
535  otv_ClassDef_validate( table + ClassDef2, otvalid );
536 
537  OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 *
538  ( len_value1 + len_value2 ) );
539 
540  otvalid->extra3 = table;
541 
542  /* Class1Record */
543  for ( ; ClassCount1 > 0; ClassCount1-- )
544  {
545  /* Class2Record */
546  for ( count = ClassCount2; count > 0; count-- )
547  {
548  if ( ValueFormat1 )
549  /* Value1 */
550  otv_ValueRecord_validate( p, ValueFormat1, otvalid );
551  p += len_value1;
552 
553  if ( ValueFormat2 )
554  /* Value2 */
555  otv_ValueRecord_validate( p, ValueFormat2, otvalid );
556  p += len_value2;
557  }
558  }
559  }
560  break;
561 
562  default:
564  }
565 
566  OTV_EXIT;
567  }
568 
569 
570  /*************************************************************************/
571  /*************************************************************************/
572  /***** *****/
573  /***** GPOS LOOKUP TYPE 3 *****/
574  /***** *****/
575  /*************************************************************************/
576  /*************************************************************************/
577 
578  static void
580  OTV_Validator otvalid )
581  {
582  FT_Bytes p = table;
583  FT_UInt PosFormat;
584 
585 
586  OTV_NAME_ENTER( "CursivePos" );
587 
588  OTV_LIMIT_CHECK( 2 );
589  PosFormat = FT_NEXT_USHORT( p );
590 
591  OTV_TRACE(( " (format %d)\n", PosFormat ));
592 
593  switch ( PosFormat )
594  {
595  case 1: /* CursivePosFormat1 */
596  {
598  FT_UInt Coverage, EntryExitCount;
599 
600  OTV_OPTIONAL_TABLE( EntryAnchor );
601  OTV_OPTIONAL_TABLE( ExitAnchor );
602 
603 
604  OTV_LIMIT_CHECK( 4 );
605  Coverage = FT_NEXT_USHORT( p );
606  EntryExitCount = FT_NEXT_USHORT( p );
607 
608  OTV_TRACE(( " (EntryExitCount = %d)\n", EntryExitCount ));
609 
610  otv_Coverage_validate( table + Coverage,
611  otvalid,
612  (FT_Int)EntryExitCount );
613 
614  OTV_LIMIT_CHECK( EntryExitCount * 4 );
615 
616  table_size = EntryExitCount * 4 + 4;
617 
618  /* EntryExitRecord */
619  for ( ; EntryExitCount > 0; EntryExitCount-- )
620  {
621  OTV_OPTIONAL_OFFSET( EntryAnchor );
622  OTV_OPTIONAL_OFFSET( ExitAnchor );
623 
624  OTV_SIZE_CHECK( EntryAnchor );
625  if ( EntryAnchor )
626  otv_Anchor_validate( table + EntryAnchor, otvalid );
627 
628  OTV_SIZE_CHECK( ExitAnchor );
629  if ( ExitAnchor )
630  otv_Anchor_validate( table + ExitAnchor, otvalid );
631  }
632  }
633  break;
634 
635  default:
637  }
638 
639  OTV_EXIT;
640  }
641 
642 
643  /*************************************************************************/
644  /*************************************************************************/
645  /***** *****/
646  /***** GPOS LOOKUP TYPE 4 *****/
647  /***** *****/
648  /*************************************************************************/
649  /*************************************************************************/
650 
651  /* UNDOCUMENTED (in OpenType 1.5): */
652  /* BaseRecord tables can contain NULL pointers. */
653 
654  /* sets otvalid->extra2 (1) */
655 
656  static void
658  OTV_Validator otvalid )
659  {
660  FT_Bytes p = table;
661  FT_UInt PosFormat;
662 
663 
664  OTV_NAME_ENTER( "MarkBasePos" );
665 
666  OTV_LIMIT_CHECK( 2 );
667  PosFormat = FT_NEXT_USHORT( p );
668 
669  OTV_TRACE(( " (format %d)\n", PosFormat ));
670 
671  switch ( PosFormat )
672  {
673  case 1:
674  otvalid->extra2 = 1;
675  OTV_NEST2( MarkBasePosFormat1, BaseArray );
676  OTV_RUN( table, otvalid );
677  break;
678 
679  default:
681  }
682 
683  OTV_EXIT;
684  }
685 
686 
687  /*************************************************************************/
688  /*************************************************************************/
689  /***** *****/
690  /***** GPOS LOOKUP TYPE 5 *****/
691  /***** *****/
692  /*************************************************************************/
693  /*************************************************************************/
694 
695  /* sets otvalid->extra2 (1) */
696 
697  static void
699  OTV_Validator otvalid )
700  {
701  FT_Bytes p = table;
702  FT_UInt PosFormat;
703 
704 
705  OTV_NAME_ENTER( "MarkLigPos" );
706 
707  OTV_LIMIT_CHECK( 2 );
708  PosFormat = FT_NEXT_USHORT( p );
709 
710  OTV_TRACE(( " (format %d)\n", PosFormat ));
711 
712  switch ( PosFormat )
713  {
714  case 1:
715  otvalid->extra2 = 1;
716  OTV_NEST3( MarkLigPosFormat1, LigatureArray, LigatureAttach );
717  OTV_RUN( table, otvalid );
718  break;
719 
720  default:
722  }
723 
724  OTV_EXIT;
725  }
726 
727 
728  /*************************************************************************/
729  /*************************************************************************/
730  /***** *****/
731  /***** GPOS LOOKUP TYPE 6 *****/
732  /***** *****/
733  /*************************************************************************/
734  /*************************************************************************/
735 
736  /* sets otvalid->extra2 (0) */
737 
738  static void
740  OTV_Validator otvalid )
741  {
742  FT_Bytes p = table;
743  FT_UInt PosFormat;
744 
745 
746  OTV_NAME_ENTER( "MarkMarkPos" );
747 
748  OTV_LIMIT_CHECK( 2 );
749  PosFormat = FT_NEXT_USHORT( p );
750 
751  OTV_TRACE(( " (format %d)\n", PosFormat ));
752 
753  switch ( PosFormat )
754  {
755  case 1:
756  otvalid->extra2 = 0;
757  OTV_NEST2( MarkMarkPosFormat1, Mark2Array );
758  OTV_RUN( table, otvalid );
759  break;
760 
761  default:
763  }
764 
765  OTV_EXIT;
766  }
767 
768 
769  /*************************************************************************/
770  /*************************************************************************/
771  /***** *****/
772  /***** GPOS LOOKUP TYPE 7 *****/
773  /***** *****/
774  /*************************************************************************/
775  /*************************************************************************/
776 
777  /* sets otvalid->extra1 (lookup count) */
778 
779  static void
781  OTV_Validator otvalid )
782  {
783  FT_Bytes p = table;
784  FT_UInt PosFormat;
785 
786 
787  OTV_NAME_ENTER( "ContextPos" );
788 
789  OTV_LIMIT_CHECK( 2 );
790  PosFormat = FT_NEXT_USHORT( p );
791 
792  OTV_TRACE(( " (format %d)\n", PosFormat ));
793 
794  switch ( PosFormat )
795  {
796  case 1:
797  /* no need to check glyph indices/classes used as input for these */
798  /* context rules since even invalid glyph indices/classes return */
799  /* meaningful results */
800 
801  otvalid->extra1 = otvalid->lookup_count;
802  OTV_NEST3( ContextPosFormat1, PosRuleSet, PosRule );
803  OTV_RUN( table, otvalid );
804  break;
805 
806  case 2:
807  /* no need to check glyph indices/classes used as input for these */
808  /* context rules since even invalid glyph indices/classes return */
809  /* meaningful results */
810 
811  OTV_NEST3( ContextPosFormat2, PosClassSet, PosClassRule );
812  OTV_RUN( table, otvalid );
813  break;
814 
815  case 3:
816  OTV_NEST1( ContextPosFormat3 );
817  OTV_RUN( table, otvalid );
818  break;
819 
820  default:
822  }
823 
824  OTV_EXIT;
825  }
826 
827 
828  /*************************************************************************/
829  /*************************************************************************/
830  /***** *****/
831  /***** GPOS LOOKUP TYPE 8 *****/
832  /***** *****/
833  /*************************************************************************/
834  /*************************************************************************/
835 
836  /* sets otvalid->extra1 (lookup count) */
837 
838  static void
840  OTV_Validator otvalid )
841  {
842  FT_Bytes p = table;
843  FT_UInt PosFormat;
844 
845 
846  OTV_NAME_ENTER( "ChainContextPos" );
847 
848  OTV_LIMIT_CHECK( 2 );
849  PosFormat = FT_NEXT_USHORT( p );
850 
851  OTV_TRACE(( " (format %d)\n", PosFormat ));
852 
853  switch ( PosFormat )
854  {
855  case 1:
856  /* no need to check glyph indices/classes used as input for these */
857  /* context rules since even invalid glyph indices/classes return */
858  /* meaningful results */
859 
860  otvalid->extra1 = otvalid->lookup_count;
861  OTV_NEST3( ChainContextPosFormat1,
862  ChainPosRuleSet, ChainPosRule );
863  OTV_RUN( table, otvalid );
864  break;
865 
866  case 2:
867  /* no need to check glyph indices/classes used as input for these */
868  /* context rules since even invalid glyph indices/classes return */
869  /* meaningful results */
870 
871  OTV_NEST3( ChainContextPosFormat2,
872  ChainPosClassSet, ChainPosClassRule );
873  OTV_RUN( table, otvalid );
874  break;
875 
876  case 3:
877  OTV_NEST1( ChainContextPosFormat3 );
878  OTV_RUN( table, otvalid );
879  break;
880 
881  default:
883  }
884 
885  OTV_EXIT;
886  }
887 
888 
889  /*************************************************************************/
890  /*************************************************************************/
891  /***** *****/
892  /***** GPOS LOOKUP TYPE 9 *****/
893  /***** *****/
894  /*************************************************************************/
895  /*************************************************************************/
896 
897  /* uses otvalid->type_funcs */
898 
899  static void
901  OTV_Validator otvalid )
902  {
903  FT_Bytes p = table;
904  FT_UInt PosFormat;
905 
906 
907  OTV_NAME_ENTER( "ExtensionPos" );
908 
909  OTV_LIMIT_CHECK( 2 );
910  PosFormat = FT_NEXT_USHORT( p );
911 
912  OTV_TRACE(( " (format %d)\n", PosFormat ));
913 
914  switch ( PosFormat )
915  {
916  case 1: /* ExtensionPosFormat1 */
917  {
918  FT_UInt ExtensionLookupType;
919  FT_ULong ExtensionOffset;
921 
922 
923  OTV_LIMIT_CHECK( 6 );
924  ExtensionLookupType = FT_NEXT_USHORT( p );
925  ExtensionOffset = FT_NEXT_ULONG( p );
926 
927  if ( ExtensionLookupType == 0 || ExtensionLookupType >= 9 )
929 
930  validate = otvalid->type_funcs[ExtensionLookupType - 1];
931  validate( table + ExtensionOffset, otvalid );
932  }
933  break;
934 
935  default:
937  }
938 
939  OTV_EXIT;
940  }
941 
942 
944  {
954  };
955 
956 
957  /* sets otvalid->type_count */
958  /* sets otvalid->type_funcs */
959 
960  FT_LOCAL_DEF( void )
962  OTV_Validator otvalid )
963  {
964  otvalid->type_count = 9;
965  otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
966 
967  otv_Lookup_validate( table, otvalid );
968  }
969 
970 
971  /*************************************************************************/
972  /*************************************************************************/
973  /***** *****/
974  /***** GPOS TABLE *****/
975  /***** *****/
976  /*************************************************************************/
977  /*************************************************************************/
978 
979  /* sets otvalid->glyph_count */
980 
981  FT_LOCAL_DEF( void )
983  FT_UInt glyph_count,
984  FT_Validator ftvalid )
985  {
986  OTV_ValidatorRec validrec;
987  OTV_Validator otvalid = &validrec;
988  FT_Bytes p = table;
991  FT_UInt ScriptList, FeatureList, LookupList;
992 
993  OTV_OPTIONAL_TABLE32( featureVariations );
994 
995 
996  otvalid->root = ftvalid;
997 
998  FT_TRACE3(( "validating GPOS table\n" ));
999  OTV_INIT;
1000 
1001  OTV_LIMIT_CHECK( 4 );
1002 
1003  if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */
1005 
1006  version = FT_NEXT_USHORT( p ); /* minorVersion */
1007 
1008  table_size = 10;
1009  switch ( version )
1010  {
1011  case 0:
1012  OTV_LIMIT_CHECK( 6 );
1013  break;
1014 
1015  case 1:
1016  OTV_LIMIT_CHECK( 10 );
1017  table_size += 4;
1018  break;
1019 
1020  default:
1022  }
1023 
1024  ScriptList = FT_NEXT_USHORT( p );
1026  LookupList = FT_NEXT_USHORT( p );
1027 
1028  otvalid->type_count = 9;
1029  otvalid->type_funcs = (OTV_Validate_Func*)otv_gpos_validate_funcs;
1030  otvalid->glyph_count = glyph_count;
1031 
1032  otv_LookupList_validate( table + LookupList,
1033  otvalid );
1035  otvalid );
1037  otvalid );
1038 
1039  if ( version > 0 )
1040  {
1041  OTV_OPTIONAL_OFFSET32( featureVariations );
1042  OTV_SIZE_CHECK32( featureVariations );
1043  if ( featureVariations )
1044  OTV_TRACE(( " [omitting featureVariations validation]\n" )); /* XXX */
1045  }
1046 
1047  FT_TRACE4(( "\n" ));
1048  }
1049 
1050 
1051 /* END */
otv_Coverage_validate(FT_Bytes table, OTV_Validator otvalid, FT_Int expected_count)
Definition: otvcommn.c:41
GLenum func
Definition: glext.h:6028
static void otv_MarkArray_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvgpos.c:309
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:337
#define OTV_EXIT
Definition: otvcommn.h:228
unsigned long FT_ULong
Definition: fttypes.h:253
#define OTV_TRACE(s)
Definition: otvcommn.h:230
static void otv_ExtensionPos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:900
otv_Lookup_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.c:353
#define OTV_OPTIONAL_TABLE(_table)
Definition: otvcommn.h:73
#define FT_INVALID_FORMAT
Definition: ftvalid.h:142
otv_GPOS_subtable_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:961
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
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define OTV_ENTER
Definition: otvcommn.h:226
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
#define OTV_OPTIONAL_OFFSET32(_offset)
Definition: otvcommn.h:85
static void otv_MarkLigPos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:698
#define OTV_NEST2(x, y)
Definition: otvcommn.h:210
struct tagFeatureList FeatureList
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
void(* OTV_Validate_Func)(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.h:41
static void otv_MarkMarkPos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:739
#define OTV_NEST1(x)
Definition: otvcommn.h:204
Definition: devices.h:37
otv_GPOS_validate(FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid)
Definition: otvgpos.c:982
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
static const WCHAR version[]
Definition: asmname.c:66
static FT_UInt otv_value_length(FT_UInt format)
Definition: otvgpos.c:153
static void otv_Anchor_validate(FT_Bytes table, OTV_Validator valid)
Definition: otvgpos.c:243
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
otv_LookupList_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.c:393
static void otv_ValueRecord_validate(FT_Bytes table, FT_UInt format, OTV_Validator otvalid)
Definition: otvgpos.c:169
static void otv_PairPos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:472
#define OTV_NAME_ENTER(name)
Definition: otvcommn.h:227
static void otv_CursivePos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:579
#define OTV_RUN
Definition: otvcommn.h:235
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
otv_ClassDef_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.c:221
#define OTV_OPTIONAL_TABLE32(_table)
Definition: otvcommn.h:76
const FT_Byte * FT_Bytes
Definition: fttypes.h:165
#define OTV_SIZE_CHECK32(_size)
Definition: otvcommn.h:119
static void otv_ChainContextPos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:839
#define OTV_LIMIT_CHECK(_count)
Definition: otvcommn.h:91
static void otv_PairSet_validate(FT_Bytes table, FT_UInt format1, FT_UInt format2, OTV_Validator otvalid)
Definition: otvgpos.c:428
static void otv_SinglePos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:348
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
static void otv_u_O_O_u_O_O(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:107
#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
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
static const ULONG BaseArray[]
Definition: hwide.c:44
otv_Device_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvcommn.c:307
#define OTV_SIZE_CHECK(_size)
Definition: otvcommn.h:97
static FRESULT validate(void *obj)
Definition: ff.c:2372
GLuint res
Definition: glext.h:9613
#define FT_INVALID_DATA
Definition: ftvalid.h:150
static void otv_ContextPos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:780
#define OTV_NEST3(x, y, z)
Definition: otvcommn.h:217
GLfloat GLfloat p
Definition: glext.h:8902
unsigned short FT_UShort
Definition: fttypes.h:209
#define OTV_OPTIONAL_OFFSET(_offset)
Definition: otvcommn.h:79
static const OTV_Validate_Func otv_gpos_validate_funcs[9]
Definition: otvgpos.c:943
static void otv_MarkBasePos_validate(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:657
static void otv_x_sxy(FT_Bytes table, OTV_Validator otvalid)
Definition: otvgpos.c:59
LOCAL int table_size
Definition: write.c:65