ReactOS  0.4.14-dev-317-g96040ec
gxvcommn.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* gxvcommn.c */
4 /* */
5 /* TrueTypeGX/AAT common tables validation (body). */
6 /* */
7 /* Copyright 2004-2018 by */
8 /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
9 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
10 /* */
11 /* This file is part of the FreeType project, and may only be used, */
12 /* modified, and distributed under the terms of the FreeType project */
13 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
14 /* this file you indicate that you have read the license and */
15 /* understand and accept it fully. */
16 /* */
17 /***************************************************************************/
18 
19 /***************************************************************************/
20 /* */
21 /* gxvalid is derived from both gxlayout module and otvalid module. */
22 /* Development of gxlayout is supported by the Information-technology */
23 /* Promotion Agency(IPA), Japan. */
24 /* */
25 /***************************************************************************/
26 
27 
28 #include "gxvcommn.h"
29 
30 
31  /*************************************************************************/
32  /* */
33  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
34  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
35  /* messages during execution. */
36  /* */
37 #undef FT_COMPONENT
38 #define FT_COMPONENT trace_gxvcommon
39 
40 
41  /*************************************************************************/
42  /*************************************************************************/
43  /***** *****/
44  /***** 16bit offset sorter *****/
45  /***** *****/
46  /*************************************************************************/
47  /*************************************************************************/
48 
49  static int
51  FT_UShort* b )
52  {
53  if ( *a < *b )
54  return -1;
55  else if ( *a > *b )
56  return 1;
57  else
58  return 0;
59  }
60 
61 
62  FT_LOCAL_DEF( void )
64  FT_UShort** length,
65  FT_UShort* buff,
66  FT_UInt nmemb,
68  GXV_Validator gxvalid )
69  {
70  FT_UInt i;
71 
72 
73  for ( i = 0; i < nmemb; i++ )
74  *(length[i]) = 0;
75 
76  for ( i = 0; i < nmemb; i++ )
77  buff[i] = offset[i];
78  buff[nmemb] = limit;
79 
80  ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ),
81  ( int(*)(const void*, const void*) )gxv_compare_ushort_offset );
82 
83  if ( buff[nmemb] > limit )
85 
86  for ( i = 0; i < nmemb; i++ )
87  {
88  FT_UInt j;
89 
90 
91  for ( j = 0; j < nmemb; j++ )
92  if ( buff[j] == offset[i] )
93  break;
94 
95  if ( j == nmemb )
97 
98  *(length[i]) = (FT_UShort)( buff[j + 1] - buff[j] );
99 
100  if ( 0 != offset[i] && 0 == *(length[i]) )
102  }
103  }
104 
105 
106  /*************************************************************************/
107  /*************************************************************************/
108  /***** *****/
109  /***** 32bit offset sorter *****/
110  /***** *****/
111  /*************************************************************************/
112  /*************************************************************************/
113 
114  static int
116  FT_ULong* b )
117  {
118  if ( *a < *b )
119  return -1;
120  else if ( *a > *b )
121  return 1;
122  else
123  return 0;
124  }
125 
126 
127  FT_LOCAL_DEF( void )
129  FT_ULong** length,
130  FT_ULong* buff,
131  FT_UInt nmemb,
132  FT_ULong limit,
133  GXV_Validator gxvalid)
134  {
135  FT_UInt i;
136 
137 
138  for ( i = 0; i < nmemb; i++ )
139  *(length[i]) = 0;
140 
141  for ( i = 0; i < nmemb; i++ )
142  buff[i] = offset[i];
143  buff[nmemb] = limit;
144 
145  ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ),
146  ( int(*)(const void*, const void*) )gxv_compare_ulong_offset );
147 
148  if ( buff[nmemb] > limit )
150 
151  for ( i = 0; i < nmemb; i++ )
152  {
153  FT_UInt j;
154 
155 
156  for ( j = 0; j < nmemb; j++ )
157  if ( buff[j] == offset[i] )
158  break;
159 
160  if ( j == nmemb )
162 
163  *(length[i]) = buff[j + 1] - buff[j];
164 
165  if ( 0 != offset[i] && 0 == *(length[i]) )
167  }
168  }
169 
170 
171  /*************************************************************************/
172  /*************************************************************************/
173  /***** *****/
174  /***** scan value array and get min & max *****/
175  /***** *****/
176  /*************************************************************************/
177  /*************************************************************************/
178 
179 
180  FT_LOCAL_DEF( void )
182  FT_Bytes limit,
183  FT_Byte* min,
184  FT_Byte* max,
185  GXV_Validator gxvalid )
186  {
187  FT_Bytes p = table;
188 
189 
190  *min = 0xFF;
191  *max = 0x00;
192 
193  while ( p < limit )
194  {
195  FT_Byte val;
196 
197 
198  GXV_LIMIT_CHECK( 1 );
199  val = FT_NEXT_BYTE( p );
200 
201  *min = (FT_Byte)FT_MIN( *min, val );
202  *max = (FT_Byte)FT_MAX( *max, val );
203  }
204 
205  gxvalid->subtable_length = (FT_ULong)( p - table );
206  }
207 
208 
209  FT_LOCAL_DEF( void )
211  FT_Bytes limit,
212  FT_UShort* min,
213  FT_UShort* max,
214  GXV_Validator gxvalid )
215  {
216  FT_Bytes p = table;
217 
218 
219  *min = 0xFFFFU;
220  *max = 0x0000;
221 
222  while ( p < limit )
223  {
224  FT_UShort val;
225 
226 
227  GXV_LIMIT_CHECK( 2 );
228  val = FT_NEXT_USHORT( p );
229 
230  *min = (FT_Byte)FT_MIN( *min, val );
231  *max = (FT_Byte)FT_MAX( *max, val );
232  }
233 
234  gxvalid->subtable_length = (FT_ULong)( p - table );
235  }
236 
237 
238  /*************************************************************************/
239  /*************************************************************************/
240  /***** *****/
241  /***** BINSEARCHHEADER *****/
242  /***** *****/
243  /*************************************************************************/
244  /*************************************************************************/
245 
246  typedef struct GXV_BinSrchHeader_
247  {
253 
255 
256 
257  static void
259  GXV_Validator gxvalid )
260  {
261  FT_UShort searchRange;
262  FT_UShort entrySelector;
263  FT_UShort rangeShift;
264 
265 
266  if ( binSrchHeader->unitSize == 0 )
268 
269  if ( binSrchHeader->nUnits == 0 )
270  {
271  if ( binSrchHeader->searchRange == 0 &&
272  binSrchHeader->entrySelector == 0 &&
273  binSrchHeader->rangeShift == 0 )
274  return;
275  else
277  }
278 
279  for ( searchRange = 1, entrySelector = 1;
280  ( searchRange * 2 ) <= binSrchHeader->nUnits &&
281  searchRange < 0x8000U;
282  searchRange *= 2, entrySelector++ )
283  ;
284 
285  entrySelector--;
286  searchRange = (FT_UShort)( searchRange * binSrchHeader->unitSize );
287  rangeShift = (FT_UShort)( binSrchHeader->nUnits * binSrchHeader->unitSize
288  - searchRange );
289 
290  if ( searchRange != binSrchHeader->searchRange ||
291  entrySelector != binSrchHeader->entrySelector ||
292  rangeShift != binSrchHeader->rangeShift )
293  {
294  GXV_TRACE(( "Inconsistency found in BinSrchHeader\n" ));
295  GXV_TRACE(( "originally: unitSize=%d, nUnits=%d, "
296  "searchRange=%d, entrySelector=%d, "
297  "rangeShift=%d\n",
298  binSrchHeader->unitSize, binSrchHeader->nUnits,
299  binSrchHeader->searchRange, binSrchHeader->entrySelector,
300  binSrchHeader->rangeShift ));
301  GXV_TRACE(( "calculated: unitSize=%d, nUnits=%d, "
302  "searchRange=%d, entrySelector=%d, "
303  "rangeShift=%d\n",
304  binSrchHeader->unitSize, binSrchHeader->nUnits,
305  searchRange, entrySelector, rangeShift ));
306 
308  }
309  }
310 
311 
312  /*
313  * parser & validator of BinSrchHeader
314  * which is used in LookupTable format 2, 4, 6.
315  *
316  * Essential parameters (unitSize, nUnits) are returned by
317  * given pointer, others (searchRange, entrySelector, rangeShift)
318  * can be calculated by essential parameters, so they are just
319  * validated and discarded.
320  *
321  * However, wrong values in searchRange, entrySelector, rangeShift
322  * won't cause fatal errors, because these parameters might be
323  * only used in old m68k font driver in MacOS.
324  * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
325  */
326 
327  FT_LOCAL_DEF( void )
329  FT_Bytes limit,
330  FT_UShort* unitSize_p,
331  FT_UShort* nUnits_p,
332  GXV_Validator gxvalid )
333  {
334  FT_Bytes p = table;
335  GXV_BinSrchHeader binSrchHeader;
336 
337 
338  GXV_NAME_ENTER( "BinSrchHeader validate" );
339 
340  if ( *unitSize_p == 0 )
341  {
342  GXV_LIMIT_CHECK( 2 );
343  binSrchHeader.unitSize = FT_NEXT_USHORT( p );
344  }
345  else
346  binSrchHeader.unitSize = *unitSize_p;
347 
348  if ( *nUnits_p == 0 )
349  {
350  GXV_LIMIT_CHECK( 2 );
351  binSrchHeader.nUnits = FT_NEXT_USHORT( p );
352  }
353  else
354  binSrchHeader.nUnits = *nUnits_p;
355 
356  GXV_LIMIT_CHECK( 2 + 2 + 2 );
357  binSrchHeader.searchRange = FT_NEXT_USHORT( p );
358  binSrchHeader.entrySelector = FT_NEXT_USHORT( p );
359  binSrchHeader.rangeShift = FT_NEXT_USHORT( p );
360  GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits ));
361 
362  gxv_BinSrchHeader_check_consistency( &binSrchHeader, gxvalid );
363 
364  if ( *unitSize_p == 0 )
365  *unitSize_p = binSrchHeader.unitSize;
366 
367  if ( *nUnits_p == 0 )
368  *nUnits_p = binSrchHeader.nUnits;
369 
370  gxvalid->subtable_length = (FT_ULong)( p - table );
371  GXV_EXIT;
372  }
373 
374 
375  /*************************************************************************/
376  /*************************************************************************/
377  /***** *****/
378  /***** LOOKUP TABLE *****/
379  /***** *****/
380  /*************************************************************************/
381  /*************************************************************************/
382 
383 #define GXV_LOOKUP_VALUE_LOAD( P, SIGNSPEC ) \
384  ( P += 2, gxv_lookup_value_load( P - 2, SIGNSPEC ) )
385 
386  static GXV_LookupValueDesc
388  int signspec )
389  {
391 
392 
393  if ( signspec == GXV_LOOKUPVALUE_UNSIGNED )
394  v.u = FT_NEXT_USHORT( p );
395  else
396  v.s = FT_NEXT_SHORT( p );
397 
398  return v;
399  }
400 
401 
402 #define GXV_UNITSIZE_VALIDATE( FORMAT, UNITSIZE, NUNITS, CORRECTSIZE ) \
403  FT_BEGIN_STMNT \
404  if ( UNITSIZE != CORRECTSIZE ) \
405  { \
406  FT_ERROR(( "unitSize=%d differs from" \
407  " expected unitSize=%d" \
408  " in LookupTable %s\n", \
409  UNITSIZE, CORRECTSIZE, FORMAT )); \
410  if ( UNITSIZE != 0 && NUNITS != 0 ) \
411  { \
412  FT_ERROR(( " cannot validate anymore\n" )); \
413  FT_INVALID_FORMAT; \
414  } \
415  else \
416  FT_ERROR(( " forcibly continues\n" )); \
417  } \
418  FT_END_STMNT
419 
420 
421  /* ================= Simple Array Format 0 Lookup Table ================ */
422  static void
424  FT_Bytes limit,
425  GXV_Validator gxvalid )
426  {
427  FT_Bytes p = table;
428  FT_UShort i;
429 
431 
432 
433  GXV_NAME_ENTER( "LookupTable format 0" );
434 
435  GXV_LIMIT_CHECK( 2 * gxvalid->face->num_glyphs );
436 
437  for ( i = 0; i < gxvalid->face->num_glyphs; i++ )
438  {
439  GXV_LIMIT_CHECK( 2 );
440  if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */
441  {
442  GXV_TRACE(( "too short, glyphs %d - %d are missing\n",
443  i, gxvalid->face->num_glyphs ));
445  break;
446  }
447 
449  gxvalid->lookupval_func( i, &value, gxvalid );
450  }
451 
452  gxvalid->subtable_length = (FT_ULong)( p - table );
453  GXV_EXIT;
454  }
455 
456 
457  /* ================= Segment Single Format 2 Lookup Table ============== */
458  /*
459  * Apple spec says:
460  *
461  * To guarantee that a binary search terminates, you must include one or
462  * more special `end of search table' values at the end of the data to
463  * be searched. The number of termination values that need to be
464  * included is table-specific. The value that indicates binary search
465  * termination is 0xFFFF.
466  *
467  * The problem is that nUnits does not include this end-marker. It's
468  * quite difficult to discriminate whether the following 0xFFFF comes from
469  * the end-marker or some next data.
470  *
471  * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
472  */
473  static void
475  FT_UShort unitSize,
476  GXV_Validator gxvalid )
477  {
478  FT_Bytes p = table;
479 
480 
481  while ( ( p + 4 ) < gxvalid->root->limit )
482  {
483  if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */
484  p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */
485  break;
486  p += unitSize;
487  }
488 
489  gxvalid->subtable_length = (FT_ULong)( p - table );
490  }
491 
492 
493  static void
495  FT_Bytes limit,
496  GXV_Validator gxvalid )
497  {
498  FT_Bytes p = table;
499  FT_UShort gid;
500 
501  FT_UShort unitSize;
502  FT_UShort nUnits;
503  FT_UShort unit;
504  FT_UShort lastGlyph;
507 
508 
509  GXV_NAME_ENTER( "LookupTable format 2" );
510 
511  unitSize = nUnits = 0;
512  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid );
513  p += gxvalid->subtable_length;
514 
515  GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 );
516 
517  for ( unit = 0, gid = 0; unit < nUnits; unit++ )
518  {
519  GXV_LIMIT_CHECK( 2 + 2 + 2 );
520  lastGlyph = FT_NEXT_USHORT( p );
523 
524  gxv_glyphid_validate( firstGlyph, gxvalid );
525  gxv_glyphid_validate( lastGlyph, gxvalid );
526 
527  if ( lastGlyph < gid )
528  {
529  GXV_TRACE(( "reverse ordered segment specification:"
530  " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
531  unit, lastGlyph, unit - 1 , gid ));
533  }
534 
535  if ( lastGlyph < firstGlyph )
536  {
537  GXV_TRACE(( "reverse ordered range specification at unit %d:",
538  " lastGlyph %d < firstGlyph %d ",
539  unit, lastGlyph, firstGlyph ));
541 
542  if ( gxvalid->root->level == FT_VALIDATE_TIGHT )
543  continue; /* ftxvalidator silently skips such an entry */
544 
545  FT_TRACE4(( "continuing with exchanged values\n" ));
546  gid = firstGlyph;
547  firstGlyph = lastGlyph;
548  lastGlyph = gid;
549  }
550 
551  for ( gid = firstGlyph; gid <= lastGlyph; gid++ )
552  gxvalid->lookupval_func( gid, &value, gxvalid );
553  }
554 
555  gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid );
556  p += gxvalid->subtable_length;
557 
558  gxvalid->subtable_length = (FT_ULong)( p - table );
559  GXV_EXIT;
560  }
561 
562 
563  /* ================= Segment Array Format 4 Lookup Table =============== */
564  static void
566  FT_Bytes limit,
567  GXV_Validator gxvalid )
568  {
569  FT_Bytes p = table;
570  FT_UShort unit;
571  FT_UShort gid;
572 
573  FT_UShort unitSize;
574  FT_UShort nUnits;
575  FT_UShort lastGlyph;
577  GXV_LookupValueDesc base_value;
579 
580 
581  GXV_NAME_ENTER( "LookupTable format 4" );
582 
583  unitSize = nUnits = 0;
584  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid );
585  p += gxvalid->subtable_length;
586 
587  GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 );
588 
589  for ( unit = 0, gid = 0; unit < nUnits; unit++ )
590  {
591  GXV_LIMIT_CHECK( 2 + 2 );
592  lastGlyph = FT_NEXT_USHORT( p );
594 
595  gxv_glyphid_validate( firstGlyph, gxvalid );
596  gxv_glyphid_validate( lastGlyph, gxvalid );
597 
598  if ( lastGlyph < gid )
599  {
600  GXV_TRACE(( "reverse ordered segment specification:"
601  " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
602  unit, lastGlyph, unit - 1 , gid ));
604  }
605 
606  if ( lastGlyph < firstGlyph )
607  {
608  GXV_TRACE(( "reverse ordered range specification at unit %d:",
609  " lastGlyph %d < firstGlyph %d ",
610  unit, lastGlyph, firstGlyph ));
612 
613  if ( gxvalid->root->level == FT_VALIDATE_TIGHT )
614  continue; /* ftxvalidator silently skips such an entry */
615 
616  FT_TRACE4(( "continuing with exchanged values\n" ));
617  gid = firstGlyph;
618  firstGlyph = lastGlyph;
619  lastGlyph = gid;
620  }
621 
622  GXV_LIMIT_CHECK( 2 );
624 
625  for ( gid = firstGlyph; gid <= lastGlyph; gid++ )
626  {
627  value = gxvalid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ),
628  &base_value,
629  limit,
630  gxvalid );
631 
632  gxvalid->lookupval_func( gid, &value, gxvalid );
633  }
634  }
635 
636  gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid );
637  p += gxvalid->subtable_length;
638 
639  gxvalid->subtable_length = (FT_ULong)( p - table );
640  GXV_EXIT;
641  }
642 
643 
644  /* ================= Segment Table Format 6 Lookup Table =============== */
645  static void
647  FT_UShort unitSize,
648  GXV_Validator gxvalid )
649  {
650  FT_Bytes p = table;
651 
652 
653  while ( p < gxvalid->root->limit )
654  {
655  if ( p[0] != 0xFF || p[1] != 0xFF )
656  break;
657  p += unitSize;
658  }
659 
660  gxvalid->subtable_length = (FT_ULong)( p - table );
661  }
662 
663 
664  static void
666  FT_Bytes limit,
667  GXV_Validator gxvalid )
668  {
669  FT_Bytes p = table;
670  FT_UShort unit;
671  FT_UShort prev_glyph;
672 
673  FT_UShort unitSize;
674  FT_UShort nUnits;
675  FT_UShort glyph;
677 
678 
679  GXV_NAME_ENTER( "LookupTable format 6" );
680 
681  unitSize = nUnits = 0;
682  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid );
683  p += gxvalid->subtable_length;
684 
685  GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 );
686 
687  for ( unit = 0, prev_glyph = 0; unit < nUnits; unit++ )
688  {
689  GXV_LIMIT_CHECK( 2 + 2 );
690  glyph = FT_NEXT_USHORT( p );
692 
693  if ( gxv_glyphid_validate( glyph, gxvalid ) )
694  GXV_TRACE(( " endmarker found within defined range"
695  " (entry %d < nUnits=%d)\n",
696  unit, nUnits ));
697 
698  if ( prev_glyph > glyph )
699  {
700  GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n",
701  glyph, prev_glyph ));
703  }
704  prev_glyph = glyph;
705 
706  gxvalid->lookupval_func( glyph, &value, gxvalid );
707  }
708 
709  gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, gxvalid );
710  p += gxvalid->subtable_length;
711 
712  gxvalid->subtable_length = (FT_ULong)( p - table );
713  GXV_EXIT;
714  }
715 
716 
717  /* ================= Trimmed Array Format 8 Lookup Table =============== */
718  static void
720  FT_Bytes limit,
721  GXV_Validator gxvalid )
722  {
723  FT_Bytes p = table;
724  FT_UShort i;
725 
728  FT_UShort glyphCount;
729 
730 
731  GXV_NAME_ENTER( "LookupTable format 8" );
732 
733  /* firstGlyph + glyphCount */
734  GXV_LIMIT_CHECK( 2 + 2 );
736  glyphCount = FT_NEXT_USHORT( p );
737 
738  gxv_glyphid_validate( firstGlyph, gxvalid );
739  gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), gxvalid );
740 
741  /* valueArray */
742  for ( i = 0; i < glyphCount; i++ )
743  {
744  GXV_LIMIT_CHECK( 2 );
746  gxvalid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, gxvalid );
747  }
748 
749  gxvalid->subtable_length = (FT_ULong)( p - table );
750  GXV_EXIT;
751  }
752 
753 
754  FT_LOCAL_DEF( void )
756  FT_Bytes limit,
757  GXV_Validator gxvalid )
758  {
759  FT_Bytes p = table;
761 
762  GXV_Validate_Func fmt_funcs_table[] =
763  {
765  NULL, /* 1 */
767  NULL, /* 3 */
769  NULL, /* 5 */
771  NULL, /* 7 */
773  };
774 
776 
777 
778  GXV_NAME_ENTER( "LookupTable" );
779 
780  /* lookuptbl_head may be used in fmt4 transit function. */
781  gxvalid->lookuptbl_head = table;
782 
783  /* format */
784  GXV_LIMIT_CHECK( 2 );
785  format = FT_NEXT_USHORT( p );
786  GXV_TRACE(( " (format %d)\n", format ));
787 
788  if ( format > 8 )
790 
791  func = fmt_funcs_table[format];
792  if ( !func )
794 
795  func( p, limit, gxvalid );
796  p += gxvalid->subtable_length;
797 
798  gxvalid->subtable_length = (FT_ULong)( p - table );
799 
800  GXV_EXIT;
801  }
802 
803 
804  /*************************************************************************/
805  /*************************************************************************/
806  /***** *****/
807  /***** Glyph ID *****/
808  /***** *****/
809  /*************************************************************************/
810  /*************************************************************************/
811 
814  GXV_Validator gxvalid )
815  {
816  FT_Face face;
817 
818 
819  if ( gid == 0xFFFFU )
820  {
821  GXV_EXIT;
822  return 1;
823  }
824 
825  face = gxvalid->face;
826  if ( face->num_glyphs < gid )
827  {
828  GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n",
829  face->num_glyphs, gid ));
831  }
832 
833  return 0;
834  }
835 
836 
837  /*************************************************************************/
838  /*************************************************************************/
839  /***** *****/
840  /***** CONTROL POINT *****/
841  /***** *****/
842  /*************************************************************************/
843  /*************************************************************************/
844 
845  FT_LOCAL_DEF( void )
847  FT_UShort ctl_point,
848  GXV_Validator gxvalid )
849  {
850  FT_Face face;
851  FT_Error error;
852 
853  FT_GlyphSlot glyph;
855  FT_UShort n_points;
856 
857 
858  face = gxvalid->face;
859 
861  gid,
863  if ( error )
865 
866  glyph = face->glyph;
867  outline = glyph->outline;
868  n_points = (FT_UShort)outline.n_points;
869 
870  if ( !( ctl_point < n_points ) )
872  }
873 
874 
875  /*************************************************************************/
876  /*************************************************************************/
877  /***** *****/
878  /***** SFNT NAME *****/
879  /***** *****/
880  /*************************************************************************/
881  /*************************************************************************/
882 
883  FT_LOCAL_DEF( void )
885  FT_UShort min_index,
886  FT_UShort max_index,
887  GXV_Validator gxvalid )
888  {
890  FT_UInt i;
891  FT_UInt nnames;
892 
893 
894  GXV_NAME_ENTER( "sfntName" );
895 
896  if ( name_index < min_index || max_index < name_index )
898 
899  nnames = FT_Get_Sfnt_Name_Count( gxvalid->face );
900  for ( i = 0; i < nnames; i++ )
901  {
902  if ( FT_Get_Sfnt_Name( gxvalid->face, i, &name ) != FT_Err_Ok )
903  continue;
904 
905  if ( name.name_id == name_index )
906  goto Out;
907  }
908 
909  GXV_TRACE(( " nameIndex = %d (UNTITLED)\n", name_index ));
911  goto Exit; /* make compiler happy */
912 
913  Out:
914  FT_TRACE1(( " nameIndex = %d (", name_index ));
916  FT_TRACE1(( ")\n" ));
917 
918  Exit:
919  GXV_EXIT;
920  }
921 
922 
923  /*************************************************************************/
924  /*************************************************************************/
925  /***** *****/
926  /***** STATE TABLE *****/
927  /***** *****/
928  /*************************************************************************/
929  /*************************************************************************/
930 
931  /* -------------------------- Class Table --------------------------- */
932 
933  /*
934  * highestClass specifies how many classes are defined in this
935  * Class Subtable. Apple spec does not mention whether undefined
936  * holes in the class (e.g.: 0-3 are predefined, 4 is unused, 5 is used)
937  * are permitted. At present, holes in a defined class are not checked.
938  * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
939  */
940 
941  static void
943  FT_UShort* length_p,
944  FT_UShort stateSize,
945  FT_Byte* maxClassID_p,
946  GXV_Validator gxvalid )
947  {
948  FT_Bytes p = table;
949  FT_Bytes limit = table + *length_p;
951  FT_UShort nGlyphs;
952 
953 
954  GXV_NAME_ENTER( "ClassTable" );
955 
956  *maxClassID_p = 3; /* Classes 0, 2, and 3 are predefined */
957 
958  GXV_LIMIT_CHECK( 2 + 2 );
960  nGlyphs = FT_NEXT_USHORT( p );
961 
962  GXV_TRACE(( " (firstGlyph = %d, nGlyphs = %d)\n", firstGlyph, nGlyphs ));
963 
964  if ( !nGlyphs )
965  goto Out;
966 
967  gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), gxvalid );
968 
969  {
970  FT_Byte nGlyphInClass[256];
971  FT_Byte classID;
972  FT_UShort i;
973 
974 
975  FT_MEM_ZERO( nGlyphInClass, 256 );
976 
977 
978  for ( i = 0; i < nGlyphs; i++ )
979  {
980  GXV_LIMIT_CHECK( 1 );
981  classID = FT_NEXT_BYTE( p );
982  switch ( classID )
983  {
984  /* following classes should not appear in class array */
985  case 0: /* end of text */
986  case 2: /* out of bounds */
987  case 3: /* end of line */
989  break;
990 
991  case 1: /* out of bounds */
992  default: /* user-defined: 4 - ( stateSize - 1 ) */
993  if ( classID >= stateSize )
994  FT_INVALID_DATA; /* assign glyph to undefined state */
995 
996  nGlyphInClass[classID]++;
997  break;
998  }
999  }
1000  *length_p = (FT_UShort)( p - table );
1001 
1002  /* scan max ClassID in use */
1003  for ( i = 0; i < stateSize; i++ )
1004  if ( ( 3 < i ) && ( nGlyphInClass[i] > 0 ) )
1005  *maxClassID_p = (FT_Byte)i; /* XXX: Check Range? */
1006  }
1007 
1008  Out:
1009  GXV_TRACE(( "Declared stateSize=0x%02x, Used maxClassID=0x%02x\n",
1010  stateSize, *maxClassID_p ));
1011  GXV_EXIT;
1012  }
1013 
1014 
1015  /* --------------------------- State Array ----------------------------- */
1016 
1017  static void
1019  FT_UShort* length_p,
1020  FT_Byte maxClassID,
1021  FT_UShort stateSize,
1022  FT_Byte* maxState_p,
1023  FT_Byte* maxEntry_p,
1024  GXV_Validator gxvalid )
1025  {
1026  FT_Bytes p = table;
1027  FT_Bytes limit = table + *length_p;
1028  FT_Byte clazz;
1029  FT_Byte entry;
1030 
1031  FT_UNUSED( stateSize ); /* for the non-debugging case */
1032 
1033 
1034  GXV_NAME_ENTER( "StateArray" );
1035 
1036  GXV_TRACE(( "parse %d bytes by stateSize=%d maxClassID=%d\n",
1037  (int)(*length_p), stateSize, (int)(maxClassID) ));
1038 
1039  /*
1040  * 2 states are predefined and must be described in StateArray:
1041  * state 0 (start of text), 1 (start of line)
1042  */
1043  GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 );
1044 
1045  *maxState_p = 0;
1046  *maxEntry_p = 0;
1047 
1048  /* read if enough to read another state */
1049  while ( p + ( 1 + maxClassID ) <= limit )
1050  {
1051  (*maxState_p)++;
1052  for ( clazz = 0; clazz <= maxClassID; clazz++ )
1053  {
1054  entry = FT_NEXT_BYTE( p );
1055  *maxEntry_p = (FT_Byte)FT_MAX( *maxEntry_p, entry );
1056  }
1057  }
1058  GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n",
1059  *maxState_p, *maxEntry_p ));
1060 
1061  *length_p = (FT_UShort)( p - table );
1062 
1063  GXV_EXIT;
1064  }
1065 
1066 
1067  /* --------------------------- Entry Table ----------------------------- */
1068 
1069  static void
1071  FT_UShort* length_p,
1072  FT_Byte maxEntry,
1073  FT_UShort stateArray,
1074  FT_UShort stateArray_length,
1075  FT_Byte maxClassID,
1076  FT_Bytes statetable_table,
1077  FT_Bytes statetable_limit,
1078  GXV_Validator gxvalid )
1079  {
1080  FT_Bytes p = table;
1081  FT_Bytes limit = table + *length_p;
1082  FT_Byte entry;
1083  FT_Byte state;
1084  FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( statetable );
1085 
1086  GXV_XStateTable_GlyphOffsetDesc glyphOffset;
1087 
1088 
1089  GXV_NAME_ENTER( "EntryTable" );
1090 
1091  GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize ));
1092 
1093  if ( ( maxEntry + 1 ) * entrySize > *length_p )
1094  {
1096 
1097  /* ftxvalidator and FontValidator both warn and continue */
1098  maxEntry = (FT_Byte)( *length_p / entrySize - 1 );
1099  GXV_TRACE(( "too large maxEntry, shrinking to %d fit EntryTable length\n",
1100  maxEntry ));
1101  }
1102 
1103  for ( entry = 0; entry <= maxEntry; entry++ )
1104  {
1105  FT_UShort newState;
1106  FT_UShort flags;
1107 
1108 
1109  GXV_LIMIT_CHECK( 2 + 2 );
1110  newState = FT_NEXT_USHORT( p );
1111  flags = FT_NEXT_USHORT( p );
1112 
1113 
1114  if ( newState < stateArray ||
1115  stateArray + stateArray_length < newState )
1116  {
1117  GXV_TRACE(( " newState offset 0x%04x is out of stateArray\n",
1118  newState ));
1120  continue;
1121  }
1122 
1123  if ( 0 != ( ( newState - stateArray ) % ( 1 + maxClassID ) ) )
1124  {
1125  GXV_TRACE(( " newState offset 0x%04x is not aligned to %d-classes\n",
1126  newState, 1 + maxClassID ));
1128  continue;
1129  }
1130 
1131  state = (FT_Byte)( ( newState - stateArray ) / ( 1 + maxClassID ) );
1132 
1133  switch ( GXV_GLYPHOFFSET_FMT( statetable ) )
1134  {
1135  case GXV_GLYPHOFFSET_NONE:
1136  glyphOffset.uc = 0; /* make compiler happy */
1137  break;
1138 
1139  case GXV_GLYPHOFFSET_UCHAR:
1140  glyphOffset.uc = FT_NEXT_BYTE( p );
1141  break;
1142 
1143  case GXV_GLYPHOFFSET_CHAR:
1144  glyphOffset.c = FT_NEXT_CHAR( p );
1145  break;
1146 
1148  glyphOffset.u = FT_NEXT_USHORT( p );
1149  break;
1150 
1151  case GXV_GLYPHOFFSET_SHORT:
1152  glyphOffset.s = FT_NEXT_SHORT( p );
1153  break;
1154 
1155  case GXV_GLYPHOFFSET_ULONG:
1156  glyphOffset.ul = FT_NEXT_ULONG( p );
1157  break;
1158 
1159  case GXV_GLYPHOFFSET_LONG:
1160  glyphOffset.l = FT_NEXT_LONG( p );
1161  break;
1162  }
1163 
1164  if ( gxvalid->statetable.entry_validate_func )
1166  flags,
1167  &glyphOffset,
1168  statetable_table,
1169  statetable_limit,
1170  gxvalid );
1171  }
1172 
1173  *length_p = (FT_UShort)( p - table );
1174 
1175  GXV_EXIT;
1176  }
1177 
1178 
1179  /* =========================== State Table ============================= */
1180 
1181  FT_LOCAL_DEF( void )
1183  FT_UShort classTable,
1184  FT_UShort stateArray,
1185  FT_UShort entryTable,
1186  FT_UShort* classTable_length_p,
1187  FT_UShort* stateArray_length_p,
1188  FT_UShort* entryTable_length_p,
1189  GXV_Validator gxvalid )
1190  {
1191  FT_UShort o[3];
1192  FT_UShort* l[3];
1193  FT_UShort buff[4];
1194 
1195 
1196  o[0] = classTable;
1197  o[1] = stateArray;
1198  o[2] = entryTable;
1199  l[0] = classTable_length_p;
1200  l[1] = stateArray_length_p;
1201  l[2] = entryTable_length_p;
1202 
1203  gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, gxvalid );
1204  }
1205 
1206 
1207  FT_LOCAL_DEF( void )
1209  FT_Bytes limit,
1210  GXV_Validator gxvalid )
1211  {
1212  FT_UShort stateSize;
1213  FT_UShort classTable; /* offset to Class(Sub)Table */
1214  FT_UShort stateArray; /* offset to StateArray */
1215  FT_UShort entryTable; /* offset to EntryTable */
1216 
1217  FT_UShort classTable_length;
1218  FT_UShort stateArray_length;
1219  FT_UShort entryTable_length;
1220  FT_Byte maxClassID;
1221  FT_Byte maxState;
1222  FT_Byte maxEntry;
1223 
1225 
1226  FT_Bytes p = table;
1227 
1228 
1229  GXV_NAME_ENTER( "StateTable" );
1230 
1231  GXV_TRACE(( "StateTable header\n" ));
1232 
1233  GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 );
1234  stateSize = FT_NEXT_USHORT( p );
1235  classTable = FT_NEXT_USHORT( p );
1236  stateArray = FT_NEXT_USHORT( p );
1237  entryTable = FT_NEXT_USHORT( p );
1238 
1239  GXV_TRACE(( "stateSize=0x%04x\n", stateSize ));
1240  GXV_TRACE(( "offset to classTable=0x%04x\n", classTable ));
1241  GXV_TRACE(( "offset to stateArray=0x%04x\n", stateArray ));
1242  GXV_TRACE(( "offset to entryTable=0x%04x\n", entryTable ));
1243 
1244  if ( stateSize > 0xFF )
1246 
1247  if ( gxvalid->statetable.optdata_load_func )
1248  gxvalid->statetable.optdata_load_func( p, limit, gxvalid );
1249 
1250  if ( gxvalid->statetable.subtable_setup_func )
1251  setup_func = gxvalid->statetable.subtable_setup_func;
1252  else
1253  setup_func = gxv_StateTable_subtable_setup;
1254 
1255  setup_func( (FT_UShort)( limit - table ),
1256  classTable,
1257  stateArray,
1258  entryTable,
1259  &classTable_length,
1260  &stateArray_length,
1261  &entryTable_length,
1262  gxvalid );
1263 
1264  GXV_TRACE(( "StateTable Subtables\n" ));
1265 
1266  if ( classTable != 0 )
1267  gxv_ClassTable_validate( table + classTable,
1268  &classTable_length,
1269  stateSize,
1270  &maxClassID,
1271  gxvalid );
1272  else
1273  maxClassID = (FT_Byte)( stateSize - 1 );
1274 
1275  if ( stateArray != 0 )
1276  gxv_StateArray_validate( table + stateArray,
1277  &stateArray_length,
1278  maxClassID,
1279  stateSize,
1280  &maxState,
1281  &maxEntry,
1282  gxvalid );
1283  else
1284  {
1285 #if 0
1286  maxState = 1; /* 0:start of text, 1:start of line are predefined */
1287 #endif
1288  maxEntry = 0;
1289  }
1290 
1291  if ( maxEntry > 0 && entryTable == 0 )
1293 
1294  if ( entryTable != 0 )
1295  gxv_EntryTable_validate( table + entryTable,
1296  &entryTable_length,
1297  maxEntry,
1298  stateArray,
1299  stateArray_length,
1300  maxClassID,
1301  table,
1302  limit,
1303  gxvalid );
1304 
1305  GXV_EXIT;
1306  }
1307 
1308 
1309  /* ================= eXtended State Table (for morx) =================== */
1310 
1311  FT_LOCAL_DEF( void )
1313  FT_ULong classTable,
1314  FT_ULong stateArray,
1315  FT_ULong entryTable,
1316  FT_ULong* classTable_length_p,
1317  FT_ULong* stateArray_length_p,
1318  FT_ULong* entryTable_length_p,
1319  GXV_Validator gxvalid )
1320  {
1321  FT_ULong o[3];
1322  FT_ULong* l[3];
1323  FT_ULong buff[4];
1324 
1325 
1326  o[0] = classTable;
1327  o[1] = stateArray;
1328  o[2] = entryTable;
1329  l[0] = classTable_length_p;
1330  l[1] = stateArray_length_p;
1331  l[2] = entryTable_length_p;
1332 
1333  gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, gxvalid );
1334  }
1335 
1336 
1337  static void
1339  GXV_LookupValueCPtr value_p,
1340  GXV_Validator gxvalid )
1341  {
1342  FT_UNUSED( glyph );
1343 
1344  if ( value_p->u >= gxvalid->xstatetable.nClasses )
1346  if ( value_p->u > gxvalid->xstatetable.maxClassID )
1347  gxvalid->xstatetable.maxClassID = value_p->u;
1348  }
1349 
1350 
1351  /*
1352  +===============+ --------+
1353  | lookup header | |
1354  +===============+ |
1355  | BinSrchHeader | |
1356  +===============+ |
1357  | lastGlyph[0] | |
1358  +---------------+ |
1359  | firstGlyph[0] | | head of lookup table
1360  +---------------+ | +
1361  | offset[0] | -> | offset [byte]
1362  +===============+ | +
1363  | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte]
1364  +---------------+ |
1365  | firstGlyph[1] | |
1366  +---------------+ |
1367  | offset[1] | |
1368  +===============+ |
1369  |
1370  .... |
1371  |
1372  16bit value array |
1373  +===============+ |
1374  | value | <-------+
1375  ....
1376  */
1377  static GXV_LookupValueDesc
1379  GXV_LookupValueCPtr base_value_p,
1380  FT_Bytes lookuptbl_limit,
1381  GXV_Validator gxvalid )
1382  {
1383  FT_Bytes p;
1384  FT_Bytes limit;
1385  FT_UShort offset;
1387 
1388  /* XXX: check range? */
1389  offset = (FT_UShort)( base_value_p->u +
1390  relative_gindex * sizeof ( FT_UShort ) );
1391 
1392  p = gxvalid->lookuptbl_head + offset;
1393  limit = lookuptbl_limit;
1394 
1395  GXV_LIMIT_CHECK ( 2 );
1396  value.u = FT_NEXT_USHORT( p );
1397 
1398  return value;
1399  }
1400 
1401 
1402  static void
1404  FT_ULong* length_p,
1405  FT_UShort maxClassID,
1406  FT_ULong stateSize,
1407  FT_UShort* maxState_p,
1408  FT_UShort* maxEntry_p,
1409  GXV_Validator gxvalid )
1410  {
1411  FT_Bytes p = table;
1412  FT_Bytes limit = table + *length_p;
1413  FT_UShort clazz;
1414  FT_UShort entry;
1415 
1416  FT_UNUSED( stateSize ); /* for the non-debugging case */
1417 
1418 
1419  GXV_NAME_ENTER( "XStateArray" );
1420 
1421  GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n",
1422  (int)(*length_p), stateSize, (int)(maxClassID) ));
1423 
1424  /*
1425  * 2 states are predefined and must be described:
1426  * state 0 (start of text), 1 (start of line)
1427  */
1428  GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 * 2 );
1429 
1430  *maxState_p = 0;
1431  *maxEntry_p = 0;
1432 
1433  /* read if enough to read another state */
1434  while ( p + ( ( 1 + maxClassID ) * 2 ) <= limit )
1435  {
1436  (*maxState_p)++;
1437  for ( clazz = 0; clazz <= maxClassID; clazz++ )
1438  {
1439  entry = FT_NEXT_USHORT( p );
1440  *maxEntry_p = (FT_UShort)FT_MAX( *maxEntry_p, entry );
1441  }
1442  }
1443  GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n",
1444  *maxState_p, *maxEntry_p ));
1445 
1446  *length_p = (FT_ULong)( p - table );
1447 
1448  GXV_EXIT;
1449  }
1450 
1451 
1452  static void
1454  FT_ULong* length_p,
1455  FT_UShort maxEntry,
1456  FT_ULong stateArray_length,
1457  FT_UShort maxClassID,
1458  FT_Bytes xstatetable_table,
1459  FT_Bytes xstatetable_limit,
1460  GXV_Validator gxvalid )
1461  {
1462  FT_Bytes p = table;
1463  FT_Bytes limit = table + *length_p;
1464  FT_UShort entry;
1465  FT_UShort state;
1466  FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( xstatetable );
1467 
1468 
1469  GXV_NAME_ENTER( "XEntryTable" );
1470  GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize ));
1471 
1472  if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit )
1474 
1475  for (entry = 0; entry <= maxEntry; entry++ )
1476  {
1477  FT_UShort newState_idx;
1478  FT_UShort flags;
1479  GXV_XStateTable_GlyphOffsetDesc glyphOffset;
1480 
1481 
1482  GXV_LIMIT_CHECK( 2 + 2 );
1483  newState_idx = FT_NEXT_USHORT( p );
1484  flags = FT_NEXT_USHORT( p );
1485 
1486  if ( stateArray_length < (FT_ULong)( newState_idx * 2 ) )
1487  {
1488  GXV_TRACE(( " newState index 0x%04x points out of stateArray\n",
1489  newState_idx ));
1491  }
1492 
1493  state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) );
1494  if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) )
1495  {
1496  FT_TRACE4(( "-> new state = %d (supposed)\n"
1497  "but newState index 0x%04x is not aligned to %d-classes\n",
1498  state, newState_idx, 1 + maxClassID ));
1500  }
1501 
1502  switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) )
1503  {
1504  case GXV_GLYPHOFFSET_NONE:
1505  glyphOffset.uc = 0; /* make compiler happy */
1506  break;
1507 
1508  case GXV_GLYPHOFFSET_UCHAR:
1509  glyphOffset.uc = FT_NEXT_BYTE( p );
1510  break;
1511 
1512  case GXV_GLYPHOFFSET_CHAR:
1513  glyphOffset.c = FT_NEXT_CHAR( p );
1514  break;
1515 
1517  glyphOffset.u = FT_NEXT_USHORT( p );
1518  break;
1519 
1520  case GXV_GLYPHOFFSET_SHORT:
1521  glyphOffset.s = FT_NEXT_SHORT( p );
1522  break;
1523 
1524  case GXV_GLYPHOFFSET_ULONG:
1525  glyphOffset.ul = FT_NEXT_ULONG( p );
1526  break;
1527 
1528  case GXV_GLYPHOFFSET_LONG:
1529  glyphOffset.l = FT_NEXT_LONG( p );
1530  break;
1531 
1532  default:
1534  goto Exit;
1535  }
1536 
1537  if ( gxvalid->xstatetable.entry_validate_func )
1539  flags,
1540  &glyphOffset,
1541  xstatetable_table,
1542  xstatetable_limit,
1543  gxvalid );
1544  }
1545 
1546  Exit:
1547  *length_p = (FT_ULong)( p - table );
1548 
1549  GXV_EXIT;
1550  }
1551 
1552 
1553  FT_LOCAL_DEF( void )
1555  FT_Bytes limit,
1556  GXV_Validator gxvalid )
1557  {
1558  /* StateHeader members */
1559  FT_ULong classTable; /* offset to Class(Sub)Table */
1560  FT_ULong stateArray; /* offset to StateArray */
1561  FT_ULong entryTable; /* offset to EntryTable */
1562 
1563  FT_ULong classTable_length;
1564  FT_ULong stateArray_length;
1565  FT_ULong entryTable_length;
1566  FT_UShort maxState;
1567  FT_UShort maxEntry;
1568 
1570 
1571  FT_Bytes p = table;
1572 
1573 
1574  GXV_NAME_ENTER( "XStateTable" );
1575 
1576  GXV_TRACE(( "XStateTable header\n" ));
1577 
1578  GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
1579  gxvalid->xstatetable.nClasses = FT_NEXT_ULONG( p );
1580  classTable = FT_NEXT_ULONG( p );
1581  stateArray = FT_NEXT_ULONG( p );
1582  entryTable = FT_NEXT_ULONG( p );
1583 
1584  GXV_TRACE(( "nClasses =0x%08x\n", gxvalid->xstatetable.nClasses ));
1585  GXV_TRACE(( "offset to classTable=0x%08x\n", classTable ));
1586  GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray ));
1587  GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable ));
1588 
1589  if ( gxvalid->xstatetable.nClasses > 0xFFFFU )
1591 
1592  GXV_TRACE(( "StateTable Subtables\n" ));
1593 
1594  if ( gxvalid->xstatetable.optdata_load_func )
1595  gxvalid->xstatetable.optdata_load_func( p, limit, gxvalid );
1596 
1597  if ( gxvalid->xstatetable.subtable_setup_func )
1598  setup_func = gxvalid->xstatetable.subtable_setup_func;
1599  else
1600  setup_func = gxv_XStateTable_subtable_setup;
1601 
1602  setup_func( (FT_ULong)( limit - table ),
1603  classTable,
1604  stateArray,
1605  entryTable,
1606  &classTable_length,
1607  &stateArray_length,
1608  &entryTable_length,
1609  gxvalid );
1610 
1611  if ( classTable != 0 )
1612  {
1613  gxvalid->xstatetable.maxClassID = 0;
1614  gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
1615  gxvalid->lookupval_func = gxv_XClassTable_lookupval_validate;
1616  gxvalid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit;
1617  gxv_LookupTable_validate( table + classTable,
1618  table + classTable + classTable_length,
1619  gxvalid );
1620 #if 0
1621  if ( gxvalid->subtable_length < classTable_length )
1622  classTable_length = gxvalid->subtable_length;
1623 #endif
1624  }
1625  else
1626  {
1627  /* XXX: check range? */
1628  gxvalid->xstatetable.maxClassID =
1629  (FT_UShort)( gxvalid->xstatetable.nClasses - 1 );
1630  }
1631 
1632  if ( stateArray != 0 )
1633  gxv_XStateArray_validate( table + stateArray,
1634  &stateArray_length,
1635  gxvalid->xstatetable.maxClassID,
1636  gxvalid->xstatetable.nClasses,
1637  &maxState,
1638  &maxEntry,
1639  gxvalid );
1640  else
1641  {
1642 #if 0
1643  maxState = 1; /* 0:start of text, 1:start of line are predefined */
1644 #endif
1645  maxEntry = 0;
1646  }
1647 
1648  if ( maxEntry > 0 && entryTable == 0 )
1650 
1651  if ( entryTable != 0 )
1652  gxv_XEntryTable_validate( table + entryTable,
1653  &entryTable_length,
1654  maxEntry,
1655  stateArray_length,
1656  gxvalid->xstatetable.maxClassID,
1657  table,
1658  limit,
1659  gxvalid );
1660 
1661  GXV_EXIT;
1662  }
1663 
1664 
1665  /*************************************************************************/
1666  /*************************************************************************/
1667  /***** *****/
1668  /***** Table overlapping *****/
1669  /***** *****/
1670  /*************************************************************************/
1671  /*************************************************************************/
1672 
1673  static int
1675  FT_ULong table1_length,
1676  FT_Bytes table2_start,
1677  FT_ULong table2_length )
1678  {
1679  if ( table1_start == table2_start )
1680  {
1681  if ( ( table1_length == 0 || table2_length == 0 ) )
1682  goto Out;
1683  }
1684  else if ( table1_start < table2_start )
1685  {
1686  if ( ( table1_start + table1_length ) <= table2_start )
1687  goto Out;
1688  }
1689  else if ( table1_start > table2_start )
1690  {
1691  if ( ( table1_start >= table2_start + table2_length ) )
1692  goto Out;
1693  }
1694  return 1;
1695 
1696  Out:
1697  return 0;
1698  }
1699 
1700 
1701  FT_LOCAL_DEF( void )
1703  FT_ULong length,
1704  const FT_String* name,
1705  GXV_odtect_Range odtect )
1706  {
1707  odtect->range[odtect->nRanges].start = start;
1708  odtect->range[odtect->nRanges].length = length;
1709  odtect->range[odtect->nRanges].name = (FT_String*)name;
1710  odtect->nRanges++;
1711  }
1712 
1713 
1714  FT_LOCAL_DEF( void )
1716  GXV_Validator gxvalid )
1717  {
1718  FT_UInt i, j;
1719 
1720 
1721  GXV_NAME_ENTER( "check overlap among multi ranges" );
1722 
1723  for ( i = 0; i < odtect->nRanges; i++ )
1724  for ( j = 0; j < i; j++ )
1725  if ( 0 != gxv_compare_ranges( odtect->range[i].start,
1726  odtect->range[i].length,
1727  odtect->range[j].start,
1728  odtect->range[j].length ) )
1729  {
1730 #ifdef FT_DEBUG_LEVEL_TRACE
1731  if ( odtect->range[i].name || odtect->range[j].name )
1732  GXV_TRACE(( "found overlap between range %d and range %d\n",
1733  i, j ));
1734  else
1735  GXV_TRACE(( "found overlap between `%s' and `%s\'\n",
1736  odtect->range[i].name,
1737  odtect->range[j].name ));
1738 #endif
1740  }
1741 
1742  GXV_EXIT;
1743  }
1744 
1745 
1746 /* END */
union value::@484 u
GLenum func
Definition: glext.h:6028
int FT_Error
Definition: fttypes.h:300
#define max(a, b)
Definition: svc.c:63
unsigned long FT_ULong
Definition: fttypes.h:253
gxv_set_length_by_ulong_offset(FT_ULong *offset, FT_ULong **length, FT_ULong *buff, FT_UInt nmemb, FT_ULong limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:128
struct GXV_BinSrchHeader_ GXV_BinSrchHeader
static void gxv_LookupTable_fmt0_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:423
gxv_StateTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1208
#define FT_NEXT_LONG(buffer)
Definition: ftstream.h:235
#define error(str)
Definition: mkdosfs.c:1605
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:235
static void gxv_LookupTable_fmt2_skip_endmarkers(FT_Bytes table, FT_UShort unitSize, GXV_Validator gxvalid)
Definition: gxvcommn.c:474
#define FT_INVALID_FORMAT
Definition: ftvalid.h:142
#define GXV_NAME_ENTER(name)
Definition: gxvcommn.h:301
signed int FT_Int
Definition: fttypes.h:220
#define GXV_TRACE(s)
Definition: gxvcommn.h:304
static int gxv_compare_ulong_offset(FT_ULong *a, FT_ULong *b)
Definition: gxvcommn.c:115
#define U(x)
Definition: wordpad.c:44
void(* GXV_StateTable_Subtable_Setup_Func)(FT_UShort table_size, FT_UShort classTable, FT_UShort stateArray, FT_UShort entryTable, FT_UShort *classTable_length_p, FT_UShort *stateArray_length_p, FT_UShort *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.h:156
GLintptr offset
Definition: glext.h:5920
FT_Long num_glyphs
Definition: freetype.h:1076
GXV_StateTable_Entry_Validate_Func entry_validate_func
Definition: gxvcommn.h:185
gxv_set_length_by_ushort_offset(FT_UShort *offset, FT_UShort **length, FT_UShort *buff, FT_UInt nmemb, FT_UShort limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:63
gxv_glyphid_validate(FT_UShort gid, GXV_Validator gxvalid)
Definition: gxvcommn.c:813
static void gxv_StateArray_validate(FT_Bytes table, FT_UShort *length_p, FT_Byte maxClassID, FT_UShort stateSize, FT_Byte *maxState_p, FT_Byte *maxEntry_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1018
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
#define FT_MIN(a, b)
Definition: ftobjs.h:71
static void gxv_LookupTable_fmt6_skip_endmarkers(FT_Bytes table, FT_UShort unitSize, GXV_Validator gxvalid)
Definition: gxvcommn.c:646
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
FT_UShort nUnits
Definition: gxvcommn.c:249
void(* GXV_Validate_Func)(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.h:82
static GXV_LookupValueDesc gxv_lookup_value_load(FT_Bytes p, int signspec)
Definition: gxvcommn.c:387
gxv_array_getlimits_byte(FT_Bytes table, FT_Bytes limit, FT_Byte *min, FT_Byte *max, GXV_Validator gxvalid)
Definition: gxvcommn.c:181
#define FT_INVALID_TOO_SHORT
Definition: ftvalid.h:134
static GXV_LookupValueDesc gxv_XClassTable_lookupfmt4_transit(FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1378
WORD face[3]
Definition: mesh.c:4747
static void gxv_LookupTable_fmt6_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:665
return FT_Err_Ok
Definition: ftbbox.c:511
#define GXV_GLYPHOFFSET_FMT(table)
Definition: gxvcommn.h:133
gxv_sfntName_validate(FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, GXV_Validator gxvalid)
Definition: gxvcommn.c:884
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GXV_LookupValue_SignSpec lookupval_sign
Definition: gxvcommn.h:246
GLint limit
Definition: glext.h:10326
static void gxv_ClassTable_validate(FT_Bytes table, FT_UShort *length_p, FT_UShort stateSize, FT_Byte *maxClassID_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:942
gxv_odtect_validate(GXV_odtect_Range odtect, GXV_Validator gxvalid)
Definition: gxvcommn.c:1715
#define GXV_SET_ERR_IF_PARANOID(err)
Definition: gxvcommn.h:66
FT_UShort searchRange
Definition: gxvcommn.c:250
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
gxv_BinSrchHeader_validate(FT_Bytes table, FT_Bytes limit, FT_UShort *unitSize_p, FT_UShort *nUnits_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:328
#define ft_qsort
Definition: ftstdlib.h:122
GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans
Definition: gxvcommn.h:248
unsigned char FT_Byte
Definition: fttypes.h:154
void(* GXV_XStateTable_Subtable_Setup_Func)(FT_ULong table_size, FT_ULong classTable, FT_ULong stateArray, FT_ULong entryTable, FT_ULong *classTable_length_p, FT_ULong *stateArray_length_p, FT_ULong *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.h:198
#define GXV_LOOKUP_VALUE_LOAD(P, SIGNSPEC)
Definition: gxvcommn.c:383
GXV_Lookup_Value_Validate_Func lookupval_func
Definition: gxvcommn.h:247
FT_UShort rangeShift
Definition: gxvcommn.c:252
static void gxv_XEntryTable_validate(FT_Bytes table, FT_ULong *length_p, FT_UShort maxEntry, FT_ULong stateArray_length, FT_UShort maxClassID, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1453
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:760
gxv_LookupTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:755
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define GXV_GLYPHOFFSET_SIZE(table)
Definition: gxvcommn.h:136
png_const_structrp png_const_inforp int * unit
Definition: png.h:2161
static void gxv_EntryTable_validate(FT_Bytes table, FT_UShort *length_p, FT_Byte maxEntry, FT_UShort stateArray, FT_UShort stateArray_length, FT_Byte maxClassID, FT_Bytes statetable_table, FT_Bytes statetable_limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1070
smooth NULL
Definition: ftsmooth.c:416
#define GXV_EXIT
Definition: gxvcommn.h:302
static void gxv_LookupTable_fmt2_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:494
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
FT_Bytes lookuptbl_head
Definition: gxvcommn.h:249
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
r l[0]
Definition: byte_order.h:167
FT_Validator root
Definition: gxvcommn.h:239
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
char FT_String
Definition: fttypes.h:187
if(!(yy_init))
Definition: macro.lex.yy.c:714
FT_UShort entrySelector
Definition: gxvcommn.c:251
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static void Exit(void)
Definition: sock.c:1331
#define FT_MAX(a, b)
Definition: ftobjs.h:72
static int gxv_compare_ranges(FT_Bytes table1_start, FT_ULong table1_length, FT_Bytes table2_start, FT_ULong table2_length)
Definition: gxvcommn.c:1674
#define GXV_UNITSIZE_VALIDATE(FORMAT, UNITSIZE, NUNITS, CORRECTSIZE)
Definition: gxvcommn.c:402
static void gxv_XClassTable_lookupval_validate(FT_UShort glyph, GXV_LookupValueCPtr value_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1338
static void gxv_XStateArray_validate(FT_Bytes table, FT_ULong *length_p, FT_UShort maxClassID, FT_ULong stateSize, FT_UShort *maxState_p, FT_UShort *maxEntry_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1403
const FT_Byte * FT_Bytes
Definition: fttypes.h:165
GXV_StateTable_ValidatorRec statetable
Definition: gxvcommn.h:254
GXV_XStateTable_Entry_Validate_Func entry_validate_func
Definition: gxvcommn.h:226
GLbitfield flags
Definition: glext.h:7161
static void gxv_LookupTable_fmt8_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:719
FT_Get_Sfnt_Name(FT_Face face, FT_UInt idx, FT_SfntName *aname)
gxv_XStateTable_subtable_setup(FT_ULong table_size, FT_ULong classTable, FT_ULong stateArray, FT_ULong entryTable, FT_ULong *classTable_length_p, FT_ULong *stateArray_length_p, FT_ULong *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1312
gxv_array_getlimits_ushort(FT_Bytes table, FT_Bytes limit, FT_UShort *min, FT_UShort *max, GXV_Validator gxvalid)
Definition: gxvcommn.c:210
gxv_ctlPoint_validate(FT_UShort gid, FT_UShort ctl_point, GXV_Validator gxvalid)
Definition: gxvcommn.c:846
FT_Outline outline
Definition: freetype.h:1927
static int state
Definition: maze.c:121
uint32_t entry
Definition: isohybrid.c:63
GLsizei const GLfloat * value
Definition: glext.h:6069
Definition: mesh.c:5329
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
FT_BEGIN_HEADER struct FT_SfntName_ FT_SfntName
#define FT_INVALID_OFFSET
Definition: ftvalid.h:138
static int gxv_compare_ushort_offset(FT_UShort *a, FT_UShort *b)
Definition: gxvcommn.c:50
static void gxv_LookupTable_fmt4_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:565
const GLdouble * v
Definition: gl.h:2040
unsigned int FT_UInt
Definition: fttypes.h:231
GLuint start
Definition: gl.h:1545
GLenum const GLvoid GLbitfield GLuint firstGlyph
Definition: glext.h:11716
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
#define min(a, b)
Definition: monoChain.cc:55
gxv_StateTable_subtable_setup(FT_UShort table_size, FT_UShort classTable, FT_UShort stateArray, FT_UShort entryTable, FT_UShort *classTable_length_p, FT_UShort *stateArray_length_p, FT_UShort *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1182
Definition: name.c:36
FT_Get_Sfnt_Name_Count(FT_Face face)
#define FT_INVALID_DATA
Definition: ftvalid.h:150
#define const
Definition: zconf.h:230
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:146
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
FT_ULong subtable_length
Definition: gxvcommn.h:244
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3012
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
gxv_odtect_add_range(FT_Bytes start, FT_ULong length, const FT_String *name, GXV_odtect_Range odtect)
Definition: gxvcommn.c:1702
GLfloat GLfloat p
Definition: glext.h:8902
#define FT_LOAD_IGNORE_TRANSFORM
Definition: freetype.h:3019
unsigned short FT_UShort
Definition: fttypes.h:209
static void gxv_BinSrchHeader_check_consistency(GXV_BinSrchHeader *binSrchHeader, GXV_Validator gxvalid)
Definition: gxvcommn.c:258
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
FT_UShort unitSize
Definition: gxvcommn.c:248
#define FT_NEXT_CHAR(buffer)
Definition: ftstream.h:217
static unsigned char buff[32768]
Definition: fatten.c:17
GXV_XStateTable_ValidatorRec xstatetable
Definition: gxvcommn.h:255
#define GXV_TRACE_HEXDUMP_SFNTNAME(n)
Definition: gxvcommn.h:359
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
#define GXV_LIMIT_CHECK(_count)
Definition: gxvcommn.h:272
gxv_XStateTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1554
LOCAL int table_size
Definition: write.c:65
GLuint const GLchar * name
Definition: glext.h:6031