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]
gxvkern.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* gxvkern.c */
4 /* */
5 /* TrueTypeGX/AAT kern table validation (body). */
6 /* */
7 /* Copyright 2004, 2005, 2006, 2007 */
8 /* by 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 "gxvalid.h"
29 #include "gxvcommn.h"
30 
31 #include FT_SFNT_NAMES_H
32 #include FT_SERVICE_GX_VALIDATE_H
33 
34 
35  /*************************************************************************/
36  /* */
37  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
38  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
39  /* messages during execution. */
40  /* */
41 #undef FT_COMPONENT
42 #define FT_COMPONENT trace_gxvkern
43 
44 
45  /*************************************************************************/
46  /*************************************************************************/
47  /***** *****/
48  /***** Data and Types *****/
49  /***** *****/
50  /*************************************************************************/
51  /*************************************************************************/
52 
53  typedef enum GXV_kern_Version_
54  {
57 
59 
60 
61  typedef enum GXV_kern_Dialect_
62  {
67 
69 
70 
71  typedef struct GXV_kern_DataRec_
72  {
74  void *subtable_data;
75  GXV_kern_Dialect dialect_request;
76 
78 
79 
80 #define GXV_KERN_DATA( field ) GXV_TABLE_DATA( kern, field )
81 
82 #define KERN_IS_CLASSIC( valid ) \
83  ( KERN_VERSION_CLASSIC == GXV_KERN_DATA( version ) )
84 #define KERN_IS_NEW( valid ) \
85  ( KERN_VERSION_NEW == GXV_KERN_DATA( version ) )
86 
87 #define KERN_DIALECT( valid ) \
88  GXV_KERN_DATA( dialect_request )
89 #define KERN_ALLOWS_MS( valid ) \
90  ( KERN_DIALECT( valid ) & KERN_DIALECT_MS )
91 #define KERN_ALLOWS_APPLE( valid ) \
92  ( KERN_DIALECT( valid ) & KERN_DIALECT_APPLE )
93 
94 #define GXV_KERN_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 4 )
95 #define GXV_KERN_SUBTABLE_HEADER_SIZE ( KERN_IS_NEW( valid ) ? 8 : 6 )
96 
97 
98  /*************************************************************************/
99  /*************************************************************************/
100  /***** *****/
101  /***** SUBTABLE VALIDATORS *****/
102  /***** *****/
103  /*************************************************************************/
104  /*************************************************************************/
105 
106 
107  /* ============================= format 0 ============================== */
108 
109  static void
110  gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes table,
111  FT_Bytes limit,
112  FT_UShort nPairs,
113  GXV_Validator valid )
114  {
115  FT_Bytes p = table;
116  FT_UShort i;
117 
118  FT_UShort last_gid_left = 0;
119  FT_UShort last_gid_right = 0;
120 
121  FT_UNUSED( limit );
122 
123 
124  GXV_NAME_ENTER( "kern format 0 pairs" );
125 
126  for ( i = 0; i < nPairs; i++ )
127  {
128  FT_UShort gid_left;
129  FT_UShort gid_right;
130 #ifdef GXV_LOAD_UNUSED_VARS
131  FT_Short kernValue;
132 #endif
133 
134 
135  /* left */
136  gid_left = FT_NEXT_USHORT( p );
137  gxv_glyphid_validate( gid_left, valid );
138 
139  /* right */
140  gid_right = FT_NEXT_USHORT( p );
141  gxv_glyphid_validate( gid_right, valid );
142 
143  /* Pairs of left and right GIDs must be unique and sorted. */
144  GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right ));
145  if ( gid_left == last_gid_left )
146  {
147  if ( last_gid_right < gid_right )
148  last_gid_right = gid_right;
149  else
151  }
152  else if ( last_gid_left < gid_left )
153  {
154  last_gid_left = gid_left;
155  last_gid_right = gid_right;
156  }
157  else
159 
160  /* skip the kern value */
161 #ifdef GXV_LOAD_UNUSED_VARS
162  kernValue = FT_NEXT_SHORT( p );
163 #else
164  p += 2;
165 #endif
166  }
167 
168  GXV_EXIT;
169  }
170 
171  static void
172  gxv_kern_subtable_fmt0_validate( FT_Bytes table,
173  FT_Bytes limit,
174  GXV_Validator valid )
175  {
177 
178  FT_UShort nPairs;
179  FT_UShort unitSize;
180 
181 
182  GXV_NAME_ENTER( "kern subtable format 0" );
183 
184  unitSize = 2 + 2 + 2;
185  nPairs = 0;
186 
187  /* nPairs, searchRange, entrySelector, rangeShift */
188  GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 );
189  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid );
190  p += 2 + 2 + 2 + 2;
191 
192  gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid );
193 
194  GXV_EXIT;
195  }
196 
197 
198  /* ============================= format 1 ============================== */
199 
200 
201  typedef struct GXV_kern_fmt1_StateOptRec_
202  {
203  FT_UShort valueTable;
204  FT_UShort valueTable_length;
205 
207 
208 
209  static void
210  gxv_kern_subtable_fmt1_valueTable_load( FT_Bytes table,
211  FT_Bytes limit,
212  GXV_Validator valid )
213  {
214  FT_Bytes p = table;
217 
218 
219  GXV_LIMIT_CHECK( 2 );
220  optdata->valueTable = FT_NEXT_USHORT( p );
221  }
222 
223 
224  /*
225  * passed tables_size covers whole StateTable, including kern fmt1 header
226  */
227  static void
228  gxv_kern_subtable_fmt1_subtable_setup( FT_UShort table_size,
229  FT_UShort classTable,
230  FT_UShort stateArray,
231  FT_UShort entryTable,
232  FT_UShort* classTable_length_p,
233  FT_UShort* stateArray_length_p,
234  FT_UShort* entryTable_length_p,
235  GXV_Validator valid )
236  {
237  FT_UShort o[4];
238  FT_UShort *l[4];
239  FT_UShort buff[5];
240 
243 
244 
245  o[0] = classTable;
246  o[1] = stateArray;
247  o[2] = entryTable;
248  o[3] = optdata->valueTable;
249  l[0] = classTable_length_p;
250  l[1] = stateArray_length_p;
251  l[2] = entryTable_length_p;
252  l[3] = &(optdata->valueTable_length);
253 
254  gxv_set_length_by_ushort_offset( o, l, buff, 4, table_size, valid );
255  }
256 
257 
258  /*
259  * passed table & limit are of whole StateTable, not including subtables
260  */
261  static void
262  gxv_kern_subtable_fmt1_entry_validate(
263  FT_Byte state,
265  GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
266  FT_Bytes table,
267  FT_Bytes limit,
268  GXV_Validator valid )
269  {
270 #ifdef GXV_LOAD_UNUSED_VARS
271  FT_UShort push;
272  FT_UShort dontAdvance;
273 #endif
274  FT_UShort valueOffset;
275 #ifdef GXV_LOAD_UNUSED_VARS
276  FT_UShort kernAction;
277  FT_UShort kernValue;
278 #endif
279 
280  FT_UNUSED( state );
281  FT_UNUSED( glyphOffset_p );
282 
283 
284 #ifdef GXV_LOAD_UNUSED_VARS
285  push = (FT_UShort)( ( flags >> 15 ) & 1 );
286  dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
287 #endif
288  valueOffset = (FT_UShort)( flags & 0x3FFF );
289 
290  {
293  FT_Bytes p;
294 
295 
296  if ( valueOffset < vt_rec->valueTable )
298 
299  p = table + valueOffset;
300  limit = table + vt_rec->valueTable + vt_rec->valueTable_length;
301 
302  GXV_LIMIT_CHECK( 2 + 2 );
303 #ifdef GXV_LOAD_UNUSED_VARS
304  kernAction = FT_NEXT_USHORT( p );
305  kernValue = FT_NEXT_USHORT( p );
306 #else
307  p += 4;
308 #endif
309  }
310  }
311 
312 
313  static void
314  gxv_kern_subtable_fmt1_validate( FT_Bytes table,
315  FT_Bytes limit,
316  GXV_Validator valid )
317  {
318  FT_Bytes p = table;
320 
321 
322  GXV_NAME_ENTER( "kern subtable format 1" );
323 
324  valid->statetable.optdata =
325  &vt_rec;
327  gxv_kern_subtable_fmt1_valueTable_load;
329  gxv_kern_subtable_fmt1_subtable_setup;
333  gxv_kern_subtable_fmt1_entry_validate;
334 
335  gxv_StateTable_validate( p, limit, valid );
336 
337  GXV_EXIT;
338  }
339 
340 
341  /* ================ Data for Class-Based Subtables 2, 3 ================ */
342 
343  typedef enum GXV_kern_ClassSpec_
344  {
347 
349 
350 
351  /* ============================= format 2 ============================== */
352 
353  /* ---------------------- format 2 specific data ----------------------- */
354 
355  typedef struct GXV_kern_subtable_fmt2_DataRec_
356  {
357  FT_UShort rowWidth;
358  FT_UShort array;
359  FT_UShort offset_min[2];
360  FT_UShort offset_max[2];
361  const FT_String* class_tag[2];
362  GXV_odtect_Range odtect;
363 
365 
366 
367 #define GXV_KERN_FMT2_DATA( field ) \
368  ( ( (GXV_kern_subtable_fmt2_DataRec *) \
369  ( GXV_KERN_DATA( subtable_data ) ) )->field )
370 
371 
372  /* -------------------------- utility functions ----------------------- */
373 
374  static void
375  gxv_kern_subtable_fmt2_clstbl_validate( FT_Bytes table,
376  FT_Bytes limit,
377  GXV_kern_ClassSpec spec,
378  GXV_Validator valid )
379  {
380  const FT_String* tag = GXV_KERN_FMT2_DATA( class_tag[spec] );
381  GXV_odtect_Range odtect = GXV_KERN_FMT2_DATA( odtect );
382 
383  FT_Bytes p = table;
385  FT_UShort nGlyphs;
386 
387 
388  GXV_NAME_ENTER( "kern format 2 classTable" );
389 
390  GXV_LIMIT_CHECK( 2 + 2 );
391  firstGlyph = FT_NEXT_USHORT( p );
392  nGlyphs = FT_NEXT_USHORT( p );
393  GXV_TRACE(( " %s firstGlyph=%d, nGlyphs=%d\n",
394  tag, firstGlyph, nGlyphs ));
395 
396  gxv_glyphid_validate( firstGlyph, valid );
397  gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), valid );
398 
399  gxv_array_getlimits_ushort( p, p + ( 2 * nGlyphs ),
400  &( GXV_KERN_FMT2_DATA( offset_min[spec] ) ),
401  &( GXV_KERN_FMT2_DATA( offset_max[spec] ) ),
402  valid );
403 
404  gxv_odtect_add_range( table, 2 * nGlyphs, tag, odtect );
405 
406  GXV_EXIT;
407  }
408 
409 
410  static void
411  gxv_kern_subtable_fmt2_validate( FT_Bytes table,
412  FT_Bytes limit,
413  GXV_Validator valid )
414  {
415  GXV_ODTECT( 3, odtect );
417  { 0, 0, { 0, 0 }, { 0, 0 }, { "leftClass", "rightClass" }, NULL };
418 
420  FT_UShort leftOffsetTable;
421  FT_UShort rightOffsetTable;
422 
423 
424  GXV_NAME_ENTER( "kern subtable format 2" );
425 
426  GXV_ODTECT_INIT( odtect );
427  fmt2_rec.odtect = odtect;
428  GXV_KERN_DATA( subtable_data ) = &fmt2_rec;
429 
430  GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 );
431  GXV_KERN_FMT2_DATA( rowWidth ) = FT_NEXT_USHORT( p );
432  leftOffsetTable = FT_NEXT_USHORT( p );
433  rightOffsetTable = FT_NEXT_USHORT( p );
434  GXV_KERN_FMT2_DATA( array ) = FT_NEXT_USHORT( p );
435 
436  GXV_TRACE(( "rowWidth = %d\n", GXV_KERN_FMT2_DATA( rowWidth ) ));
437 
438 
439  GXV_LIMIT_CHECK( leftOffsetTable );
440  GXV_LIMIT_CHECK( rightOffsetTable );
442 
443  gxv_kern_subtable_fmt2_clstbl_validate( table + leftOffsetTable, limit,
444  GXV_KERN_CLS_L, valid );
445 
446  gxv_kern_subtable_fmt2_clstbl_validate( table + rightOffsetTable, limit,
447  GXV_KERN_CLS_R, valid );
448 
449  if ( GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_L] ) +
450  GXV_KERN_FMT2_DATA( offset_min[GXV_KERN_CLS_R] )
451  < GXV_KERN_FMT2_DATA( array ) )
453 
455  GXV_KERN_FMT2_DATA( offset_max[GXV_KERN_CLS_L] )
456  + GXV_KERN_FMT2_DATA( offset_max[GXV_KERN_CLS_R] )
457  - GXV_KERN_FMT2_DATA( array ),
458  "array", odtect );
459 
460  gxv_odtect_validate( odtect, valid );
461 
462  GXV_EXIT;
463  }
464 
465 
466  /* ============================= format 3 ============================== */
467 
468  static void
469  gxv_kern_subtable_fmt3_validate( FT_Bytes table,
470  FT_Bytes limit,
471  GXV_Validator valid )
472  {
474  FT_UShort glyphCount;
475  FT_Byte kernValueCount;
476  FT_Byte leftClassCount;
477  FT_Byte rightClassCount;
478  FT_Byte flags;
479 
480 
481  GXV_NAME_ENTER( "kern subtable format 3" );
482 
483  GXV_LIMIT_CHECK( 2 + 1 + 1 + 1 + 1 );
484  glyphCount = FT_NEXT_USHORT( p );
485  kernValueCount = FT_NEXT_BYTE( p );
486  leftClassCount = FT_NEXT_BYTE( p );
487  rightClassCount = FT_NEXT_BYTE( p );
488  flags = FT_NEXT_BYTE( p );
489 
490  if ( valid->face->num_glyphs != glyphCount )
491  {
492  GXV_TRACE(( "maxGID=%d, but glyphCount=%d\n",
493  valid->face->num_glyphs, glyphCount ));
495  }
496 
497  if ( flags != 0 )
498  GXV_TRACE(( "kern subtable fmt3 has nonzero value"
499  " (%d) in unused flag\n", flags ));
500  /*
501  * just skip kernValue[kernValueCount]
502  */
503  GXV_LIMIT_CHECK( 2 * kernValueCount );
504  p += 2 * kernValueCount;
505 
506  /*
507  * check leftClass[gid] < leftClassCount
508  */
509  {
510  FT_Byte min, max;
511 
512 
513  GXV_LIMIT_CHECK( glyphCount );
514  gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid );
515  p += valid->subtable_length;
516 
517  if ( leftClassCount < max )
519  }
520 
521  /*
522  * check rightClass[gid] < rightClassCount
523  */
524  {
525  FT_Byte min, max;
526 
527 
528  GXV_LIMIT_CHECK( glyphCount );
529  gxv_array_getlimits_byte( p, p + glyphCount, &min, &max, valid );
530  p += valid->subtable_length;
531 
532  if ( rightClassCount < max )
534  }
535 
536  /*
537  * check kernIndex[i, j] < kernValueCount
538  */
539  {
540  FT_UShort i, j;
541 
542 
543  for ( i = 0; i < leftClassCount; i++ )
544  {
545  for ( j = 0; j < rightClassCount; j++ )
546  {
547  GXV_LIMIT_CHECK( 1 );
548  if ( kernValueCount < FT_NEXT_BYTE( p ) )
550  }
551  }
552  }
553 
554  valid->subtable_length = p - table;
555 
556  GXV_EXIT;
557  }
558 
559 
560  static FT_Bool
561  gxv_kern_coverage_new_apple_validate( FT_UShort coverage,
562  FT_UShort* format,
563  GXV_Validator valid )
564  {
565  /* new Apple-dialect */
566 #ifdef GXV_LOAD_TRACE_VARS
567  FT_Bool kernVertical;
568  FT_Bool kernCrossStream;
569  FT_Bool kernVariation;
570 #endif
571 
572  FT_UNUSED( valid );
573 
574 
575  /* reserved bits = 0 */
576  if ( coverage & 0x1FFC )
577  return FALSE;
578 
579 #ifdef GXV_LOAD_TRACE_VARS
580  kernVertical = FT_BOOL( ( coverage >> 15 ) & 1 );
581  kernCrossStream = FT_BOOL( ( coverage >> 14 ) & 1 );
582  kernVariation = FT_BOOL( ( coverage >> 13 ) & 1 );
583 #endif
584 
585  *format = (FT_UShort)( coverage & 0x0003 );
586 
587  GXV_TRACE(( "new Apple-dialect: "
588  "horizontal=%d, cross-stream=%d, variation=%d, format=%d\n",
589  !kernVertical, kernCrossStream, kernVariation, *format ));
590 
591  GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" ));
592 
593  return TRUE;
594  }
595 
596 
597  static FT_Bool
598  gxv_kern_coverage_classic_apple_validate( FT_UShort coverage,
599  FT_UShort* format,
600  GXV_Validator valid )
601  {
602  /* classic Apple-dialect */
603 #ifdef GXV_LOAD_TRACE_VARS
604  FT_Bool horizontal;
605  FT_Bool cross_stream;
606 #endif
607 
608 
609  /* check expected flags, but don't check if MS-dialect is impossible */
610  if ( !( coverage & 0xFD00 ) && KERN_ALLOWS_MS( valid ) )
611  return FALSE;
612 
613  /* reserved bits = 0 */
614  if ( coverage & 0x02FC )
615  return FALSE;
616 
617 #ifdef GXV_LOAD_TRACE_VARS
618  horizontal = FT_BOOL( ( coverage >> 15 ) & 1 );
619  cross_stream = FT_BOOL( ( coverage >> 13 ) & 1 );
620 #endif
621 
622  *format = (FT_UShort)( coverage & 0x0003 );
623 
624  GXV_TRACE(( "classic Apple-dialect: "
625  "horizontal=%d, cross-stream=%d, format=%d\n",
626  horizontal, cross_stream, *format ));
627 
628  /* format 1 requires GX State Machine, too new for classic */
629  if ( *format == 1 )
630  return FALSE;
631 
632  GXV_TRACE(( "kerning values in Apple format subtable are ignored\n" ));
633 
634  return TRUE;
635  }
636 
637 
638  static FT_Bool
639  gxv_kern_coverage_classic_microsoft_validate( FT_UShort coverage,
640  FT_UShort* format,
641  GXV_Validator valid )
642  {
643  /* classic Microsoft-dialect */
644 #ifdef GXV_LOAD_TRACE_VARS
645  FT_Bool horizontal;
646  FT_Bool minimum;
647  FT_Bool cross_stream;
648  FT_Bool override;
649 #endif
650 
651  FT_UNUSED( valid );
652 
653 
654  /* reserved bits = 0 */
655  if ( coverage & 0xFDF0 )
656  return FALSE;
657 
658 #ifdef GXV_LOAD_TRACE_VARS
659  horizontal = FT_BOOL( coverage & 1 );
660  minimum = FT_BOOL( ( coverage >> 1 ) & 1 );
661  cross_stream = FT_BOOL( ( coverage >> 2 ) & 1 );
662  override = FT_BOOL( ( coverage >> 3 ) & 1 );
663 #endif
664 
665  *format = (FT_UShort)( ( coverage >> 8 ) & 0x0003 );
666 
667  GXV_TRACE(( "classic Microsoft-dialect: "
668  "horizontal=%d, minimum=%d, cross-stream=%d, "
669  "override=%d, format=%d\n",
670  horizontal, minimum, cross_stream, override, *format ));
671 
672  if ( *format == 2 )
673  GXV_TRACE((
674  "kerning values in Microsoft format 2 subtable are ignored\n" ));
675 
676  return TRUE;
677  }
678 
679 
680  /*************************************************************************/
681  /*************************************************************************/
682  /***** *****/
683  /***** MAIN *****/
684  /***** *****/
685  /*************************************************************************/
686  /*************************************************************************/
687 
688  static GXV_kern_Dialect
689  gxv_kern_coverage_validate( FT_UShort coverage,
690  FT_UShort* format,
691  GXV_Validator valid )
692  {
694 
695 
696  GXV_NAME_ENTER( "validating coverage" );
697 
698  GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage ));
699 
700  if ( KERN_IS_NEW( valid ) )
701  {
702  if ( gxv_kern_coverage_new_apple_validate( coverage,
703  format,
704  valid ) )
705  {
706  result = KERN_DIALECT_APPLE;
707  goto Exit;
708  }
709  }
710 
711  if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_APPLE( valid ) )
712  {
713  if ( gxv_kern_coverage_classic_apple_validate( coverage,
714  format,
715  valid ) )
716  {
717  result = KERN_DIALECT_APPLE;
718  goto Exit;
719  }
720  }
721 
722  if ( KERN_IS_CLASSIC( valid ) && KERN_ALLOWS_MS( valid ) )
723  {
724  if ( gxv_kern_coverage_classic_microsoft_validate( coverage,
725  format,
726  valid ) )
727  {
728  result = KERN_DIALECT_MS;
729  goto Exit;
730  }
731  }
732 
733  GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" ));
734 
735  Exit:
736  GXV_EXIT;
737  return result;
738  }
739 
740 
741  static void
742  gxv_kern_subtable_validate( FT_Bytes table,
743  FT_Bytes limit,
744  GXV_Validator valid )
745  {
746  FT_Bytes p = table;
747 #ifdef GXV_LOAD_TRACE_VARS
748  FT_UShort version = 0; /* MS only: subtable version, unused */
749 #endif
750  FT_ULong length; /* MS: 16bit, Apple: 32bit*/
751  FT_UShort coverage;
752 #ifdef GXV_LOAD_TRACE_VARS
753  FT_UShort tupleIndex = 0; /* Apple only */
754 #endif
755  FT_UShort u16[2];
756  FT_UShort format = 255; /* subtable format */
757 
758 
759  GXV_NAME_ENTER( "kern subtable" );
760 
761  GXV_LIMIT_CHECK( 2 + 2 + 2 );
762  u16[0] = FT_NEXT_USHORT( p ); /* Apple: length_hi MS: version */
763  u16[1] = FT_NEXT_USHORT( p ); /* Apple: length_lo MS: length */
764  coverage = FT_NEXT_USHORT( p );
765 
766  switch ( gxv_kern_coverage_validate( coverage, &format, valid ) )
767  {
768  case KERN_DIALECT_MS:
769 #ifdef GXV_LOAD_TRACE_VARS
770  version = u16[0];
771 #endif
772  length = u16[1];
773 #ifdef GXV_LOAD_TRACE_VARS
774  tupleIndex = 0;
775 #endif
776  GXV_TRACE(( "Subtable version = %d\n", version ));
777  GXV_TRACE(( "Subtable length = %d\n", length ));
778  break;
779 
780  case KERN_DIALECT_APPLE:
781 #ifdef GXV_LOAD_TRACE_VARS
782  version = 0;
783 #endif
784  length = ( u16[0] << 16 ) + u16[1];
785 #ifdef GXV_LOAD_TRACE_VARS
786  tupleIndex = 0;
787 #endif
788  GXV_TRACE(( "Subtable length = %d\n", length ));
789 
790  if ( KERN_IS_NEW( valid ) )
791  {
792  GXV_LIMIT_CHECK( 2 );
793 #ifdef GXV_LOAD_TRACE_VARS
794  tupleIndex = FT_NEXT_USHORT( p );
795 #else
796  p += 2;
797 #endif
798  GXV_TRACE(( "Subtable tupleIndex = %d\n", tupleIndex ));
799  }
800  break;
801 
802  default:
803  length = u16[1];
804  GXV_TRACE(( "cannot detect subtable dialect, "
805  "just skip %d byte\n", length ));
806  goto Exit;
807  }
808 
809  /* formats 1, 2, 3 require the position of the start of this subtable */
810  if ( format == 0 )
811  gxv_kern_subtable_fmt0_validate( table, table + length, valid );
812  else if ( format == 1 )
813  gxv_kern_subtable_fmt1_validate( table, table + length, valid );
814  else if ( format == 2 )
815  gxv_kern_subtable_fmt2_validate( table, table + length, valid );
816  else if ( format == 3 )
817  gxv_kern_subtable_fmt3_validate( table, table + length, valid );
818  else
820 
821  Exit:
822  valid->subtable_length = length;
823  GXV_EXIT;
824  }
825 
826 
827  /*************************************************************************/
828  /*************************************************************************/
829  /***** *****/
830  /***** kern TABLE *****/
831  /***** *****/
832  /*************************************************************************/
833  /*************************************************************************/
834 
835  static void
836  gxv_kern_validate_generic( FT_Bytes table,
837  FT_Face face,
838  FT_Bool classic_only,
839  GXV_kern_Dialect dialect_request,
840  FT_Validator ftvalid )
841  {
842  GXV_ValidatorRec validrec;
843  GXV_Validator valid = &validrec;
844 
845  GXV_kern_DataRec kernrec;
846  GXV_kern_Data kern = &kernrec;
847 
848  FT_Bytes p = table;
849  FT_Bytes limit = 0;
850 
851  FT_ULong nTables = 0;
852  FT_UInt i;
853 
854 
855  valid->root = ftvalid;
856  valid->table_data = kern;
857  valid->face = face;
858 
859  FT_TRACE3(( "validating `kern' table\n" ));
860  GXV_INIT;
861  KERN_DIALECT( valid ) = dialect_request;
862 
863  GXV_LIMIT_CHECK( 2 );
865  GXV_TRACE(( "version 0x%04x (higher 16bit)\n",
866  GXV_KERN_DATA( version ) ));
867 
868  if ( 0x0001 < GXV_KERN_DATA( version ) )
870  else if ( KERN_IS_CLASSIC( valid ) )
871  {
872  GXV_LIMIT_CHECK( 2 );
873  nTables = FT_NEXT_USHORT( p );
874  }
875  else if ( KERN_IS_NEW( valid ) )
876  {
877  if ( classic_only )
879 
880  if ( 0x0000 != FT_NEXT_USHORT( p ) )
882 
883  GXV_LIMIT_CHECK( 4 );
884  nTables = FT_NEXT_ULONG( p );
885  }
886 
887  for ( i = 0; i < nTables; i++ )
888  {
889  GXV_TRACE(( "validating subtable %d/%d\n", i, nTables ));
890  /* p should be 32bit-aligned? */
891  gxv_kern_subtable_validate( p, 0, valid );
892  p += valid->subtable_length;
893  }
894 
895  FT_TRACE4(( "\n" ));
896  }
897 
898 
899  FT_LOCAL_DEF( void )
901  FT_Face face,
902  FT_Validator ftvalid )
903  {
904  gxv_kern_validate_generic( table, face, 0, KERN_DIALECT_ANY, ftvalid );
905  }
906 
907 
908  FT_LOCAL_DEF( void )
910  FT_Face face,
911  FT_Int dialect_flags,
912  FT_Validator ftvalid )
913  {
914  GXV_kern_Dialect dialect_request;
915 
916 
917  dialect_request = (GXV_kern_Dialect)dialect_flags;
918  gxv_kern_validate_generic( table, face, 1, dialect_request, ftvalid );
919  }
920 
921 
922 /* END */
GLenum GLuint GLenum GLsizei length
#define GXV_KERN_SUBTABLE_HEADER_SIZE
Definition: gxvkern.c:95
local int push(void *desc, unsigned char *buf, unsigned len)
Definition: infcover.c:463
enum GXV_kern_ClassSpec_ GXV_kern_ClassSpec
unsigned long FT_ULong
Definition: fttypes.h:249
GLfloat GLfloat p
#define FT_VALIDATE_APPLE
Definition: ftgxval.h:275
struct GXV_kern_subtable_fmt2_DataRec_ * GXV_kern_subtable_fmt2_Data
GXV_StateTable_Subtable_Setup_Func subtable_setup_func
Definition: gxvcommn.h:184
#define FT_INVALID_FORMAT
Definition: ftvalid.h:133
#define NULL
Definition: ftobjs.h:61
#define GXV_NAME_ENTER(name)
Definition: gxvcommn.h:301
signed int FT_Int
Definition: fttypes.h:216
#define GXV_TRACE(s)
Definition: gxvcommn.h:304
#define KERN_DIALECT(valid)
Definition: gxvkern.c:87
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
struct GXV_kern_DataRec_ GXV_kern_DataRec
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
GXV_kern_Dialect_
Definition: gxvkern.c:61
#define GXV_ODTECT(n, odtect)
Definition: gxvcommn.h:562
GXV_kern_ClassSpec_
Definition: gxvkern.c:343
gxv_BinSrchHeader_validate(FT_Bytes table, FT_Bytes limit, FT_UShort *unitSize_p, FT_UShort *nUnits_p, GXV_Validator valid)
Definition: gxvcommn.c:328
void * table_data
Definition: gxvcommn.h:242
png_uint_32 i
Definition: png.h:2640
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
#define GXV_SET_ERR_IF_PARANOID(err)
Definition: gxvcommn.h:66
GLenum GLuint GLint GLenum face
GXV_StateTable_Entry_Validate_Func entry_validate_func
Definition: gxvcommn.h:185
unsigned char FT_Byte
Definition: fttypes.h:150
enum GXV_kern_Version_ GXV_kern_Version
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define KERN_IS_CLASSIC(valid)
Definition: gxvkern.c:82
enum GXV_kern_Dialect_ GXV_kern_Dialect
GXV_StateTable_ValidatorRec statetable
Definition: gxvcommn.h:254
GXV_GlyphOffset_Format entry_glyphoffset_fmt
Definition: gxvcommn.h:181
#define GXV_EXIT
Definition: gxvcommn.h:302
struct GXV_kern_fmt1_StateOptRec_ * GXV_kern_fmt1_StateOptRecData
GXV_StateTable_OptData_Load_Func optdata_load_func
Definition: gxvcommn.h:186
#define GXV_KERN_FMT2_DATA(field)
Definition: gxvkern.c:367
char FT_String
Definition: fttypes.h:183
GLbitfield flags
float min(float a, float b)
Definition: Vector2.hpp:307
GLenum const GLvoid GLbitfield GLuint firstGlyph
#define KERN_ALLOWS_MS(valid)
Definition: gxvkern.c:89
#define FT_VALIDATE_MS
Definition: ftgxval.h:274
typedefFT_BEGIN_HEADER struct FT_ValidatorRec_ volatile * FT_Validator
Definition: ftvalid.h:42
int const char * version
Definition: zlib.h:813
#define GXV_ODTECT_INIT(odtect)
Definition: gxvcommn.h:567
const FT_Byte * FT_Bytes
Definition: fttypes.h:161
#define FALSE
Definition: ftobjs.h:57
signed short FT_Short
Definition: fttypes.h:194
gxv_kern_validate(FT_Bytes table, FT_Face face, FT_Validator ftvalid)
Definition: gxvkern.c:900
gxv_odtect_validate(GXV_odtect_Range odtect, GXV_Validator valid)
Definition: gxvcommn.c:1715
local int max
Definition: enough.c:170
#define FT_BOOL(x)
Definition: fttypes.h:574
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
if(!abbox) return FT_THROW(Invalid_Argument)
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
#define FT_INVALID_OFFSET
Definition: ftvalid.h:129
FT_Long num_glyphs
Definition: freetype.h:927
#define KERN_ALLOWS_APPLE(valid)
Definition: gxvkern.c:91
GLuint64EXT * result
#define FT_VALIDATE_CKERN
Definition: ftgxval.h:277
unsigned int FT_UInt
Definition: fttypes.h:227
gxv_set_length_by_ushort_offset(FT_UShort *offset, FT_UShort **length, FT_UShort *buff, FT_UInt nmemb, FT_UShort limit, GXV_Validator valid)
Definition: gxvcommn.c:63
struct GXV_kern_DataRec_ * GXV_kern_Data
FT_ULong subtable_length
Definition: gxvcommn.h:244
gxv_array_getlimits_byte(FT_Bytes table, FT_Bytes limit, FT_Byte *min, FT_Byte *max, GXV_Validator valid)
Definition: gxvcommn.c:181
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:238
FT_Validator root
Definition: gxvcommn.h:239
gxv_kern_validate_classic(FT_Bytes table, FT_Face face, FT_Int dialect_flags, FT_Validator ftvalid)
Definition: gxvkern.c:909
#define FT_INVALID_DATA
Definition: ftvalid.h:141
struct GXV_kern_fmt1_StateOptRec_ GXV_kern_fmt1_StateOptRec
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:137
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
GXV_kern_Version_
Definition: gxvkern.c:53
gxv_odtect_add_range(FT_Bytes start, FT_ULong length, const FT_String *name, GXV_odtect_Range odtect)
Definition: gxvcommn.c:1702
unsigned short FT_UShort
Definition: fttypes.h:205
GLenum GLsizei GLenum GLenum const GLvoid * table
#define GXV_INIT
Definition: gxvcommn.h:300
unsigned short u16
16 bits unsigned integer
Definition: std_types.hpp:47
gxv_StateTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator valid)
Definition: gxvcommn.c:1214
#define GXV_KERN_DATA(field)
Definition: gxvkern.c:80
#define TRUE
Definition: ftobjs.h:53
gxv_glyphid_validate(FT_UShort gid, GXV_Validator valid)
Definition: gxvcommn.c:813
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
gxv_array_getlimits_ushort(FT_Bytes table, FT_Bytes limit, FT_UShort *min, FT_UShort *max, GXV_Validator valid)
Definition: gxvcommn.c:210
GLint limit
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
#define KERN_IS_NEW(valid)
Definition: gxvkern.c:84
#define GXV_LIMIT_CHECK(_count)
Definition: gxvcommn.h:272
struct GXV_kern_subtable_fmt2_DataRec_ GXV_kern_subtable_fmt2_DataRec