41#define FT_COMPONENT gxvjust
58 FT_UShort wdc_offset_max;
59 FT_UShort wdc_offset_min;
60 FT_UShort pc_offset_max;
61 FT_UShort pc_offset_min;
63 } GXV_just_DataRec, *GXV_just_Data;
66#define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a )
71 gxv_just_check_max_gid( FT_UShort gid,
72 const FT_String* msg_tag,
73 GXV_Validator gxvalid )
77 if ( gid < gxvalid->face->num_glyphs )
80 GXV_TRACE((
"just table includes too large %s"
81 " GID=%d > %ld (in maxp)\n",
82 msg_tag, gid, gxvalid->face->num_glyphs ));
83 GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
88 gxv_just_wdp_entry_validate( FT_Bytes table,
90 GXV_Validator gxvalid )
94#ifdef GXV_LOAD_UNUSED_VARS
95 FT_Fixed beforeGrowLimit;
96 FT_Fixed beforeShrinkGrowLimit;
97 FT_Fixed afterGrowLimit;
98 FT_Fixed afterShrinkGrowLimit;
100 FT_UShort shrinkFlags;
104 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
105 justClass = FT_NEXT_ULONG( p );
106#ifndef GXV_LOAD_UNUSED_VARS
107 p += 4 + 4 + 4 + 4 + 2 + 2;
109 beforeGrowLimit = FT_NEXT_ULONG( p );
110 beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
111 afterGrowLimit = FT_NEXT_ULONG( p );
112 afterShrinkGrowLimit = FT_NEXT_ULONG( p );
113 growFlags = FT_NEXT_USHORT( p );
114 shrinkFlags = FT_NEXT_USHORT( p );
118 if ( ( justClass & 0xFFFFFF80UL ) != 0 )
120 GXV_TRACE((
"just table includes non-zero value"
121 " in unused justClass higher bits"
122 " of WidthDeltaPair" ));
123 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
126 gxvalid->subtable_length = (FT_ULong)( p - table );
131 gxv_just_wdc_entry_validate( FT_Bytes table,
133 GXV_Validator gxvalid )
139 GXV_LIMIT_CHECK( 4 );
140 count = FT_NEXT_ULONG( p );
141 for ( i = 0; i < count; i++ )
143 GXV_TRACE((
"validating wdc pair %lu/%lu\n", i + 1, count ));
144 gxv_just_wdp_entry_validate( p, limit, gxvalid );
145 p += gxvalid->subtable_length;
148 gxvalid->subtable_length = (FT_ULong)( p - table );
153 gxv_just_widthDeltaClusters_validate( FT_Bytes table,
155 GXV_Validator gxvalid )
158 FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max );
161 GXV_NAME_ENTER(
"just justDeltaClusters" );
163 if ( limit <= wdc_end )
166 while ( p <= wdc_end )
168 gxv_just_wdc_entry_validate( p, limit, gxvalid );
169 p += gxvalid->subtable_length;
172 gxvalid->subtable_length = (FT_ULong)( p - table );
179 gxv_just_actSubrecord_type0_validate( FT_Bytes table,
181 GXV_Validator gxvalid )
187#ifdef GXV_LOAD_UNUSED_VARS
190 FT_UShort decomposedCount;
195 GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
196 lowerLimit = FT_NEXT_LONG( p );
197 upperLimit = FT_NEXT_LONG( p );
198#ifdef GXV_LOAD_UNUSED_VARS
199 order = FT_NEXT_USHORT( p );
203 decomposedCount = FT_NEXT_USHORT( p );
205 if ( lowerLimit >= upperLimit )
207 GXV_TRACE((
"just table includes invalid range spec:"
208 " lowerLimit(%ld) > upperLimit(%ld)\n",
209 lowerLimit, upperLimit ));
210 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
213 for ( i = 0; i < decomposedCount; i++ )
218 GXV_LIMIT_CHECK( 2 );
219 glyphs = FT_NEXT_USHORT( p );
220 gxv_just_check_max_gid( glyphs,
"type0:glyphs", gxvalid );
223 gxvalid->subtable_length = (FT_ULong)( p - table );
228 gxv_just_actSubrecord_type1_validate( FT_Bytes table,
230 GXV_Validator gxvalid )
236 GXV_LIMIT_CHECK( 2 );
237 addGlyph = FT_NEXT_USHORT( p );
239 gxv_just_check_max_gid( addGlyph,
"type1:addGlyph", gxvalid );
241 gxvalid->subtable_length = (FT_ULong)( p - table );
246 gxv_just_actSubrecord_type2_validate( FT_Bytes table,
248 GXV_Validator gxvalid )
251#ifdef GXV_LOAD_UNUSED_VARS
252 FT_Fixed substThreshhold;
255 FT_UShort substGlyph;
258 GXV_LIMIT_CHECK( 4 + 2 + 2 );
259#ifdef GXV_LOAD_UNUSED_VARS
260 substThreshhold = FT_NEXT_ULONG( p );
264 addGlyph = FT_NEXT_USHORT( p );
265 substGlyph = FT_NEXT_USHORT( p );
267 if ( addGlyph != 0xFFFF )
268 gxv_just_check_max_gid( addGlyph,
"type2:addGlyph", gxvalid );
270 gxv_just_check_max_gid( substGlyph,
"type2:substGlyph", gxvalid );
272 gxvalid->subtable_length = (FT_ULong)( p - table );
277 gxv_just_actSubrecord_type4_validate( FT_Bytes table,
279 GXV_Validator gxvalid )
282 FT_ULong variantsAxis;
283 FT_Fixed minimumLimit;
284 FT_Fixed noStretchValue;
285 FT_Fixed maximumLimit;
288 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
289 variantsAxis = FT_NEXT_ULONG( p );
290 minimumLimit = FT_NEXT_LONG( p );
291 noStretchValue = FT_NEXT_LONG( p );
292 maximumLimit = FT_NEXT_LONG( p );
294 gxvalid->subtable_length = (FT_ULong)( p - table );
296 if ( variantsAxis != 0x64756374L )
297 GXV_TRACE((
"variantsAxis 0x%08lx is non default value",
300 if ( minimumLimit > noStretchValue )
301 GXV_TRACE((
"type4:minimumLimit 0x%08lx > noStretchValue 0x%08lx\n",
302 minimumLimit, noStretchValue ));
303 else if ( noStretchValue > maximumLimit )
304 GXV_TRACE((
"type4:noStretchValue 0x%08lx > maximumLimit 0x%08lx\n",
305 noStretchValue, maximumLimit ));
306 else if ( !IS_PARANOID_VALIDATION )
314 gxv_just_actSubrecord_type5_validate( FT_Bytes table,
316 GXV_Validator gxvalid )
323 GXV_LIMIT_CHECK( 2 + 2 );
324 flags = FT_NEXT_USHORT( p );
325 glyph = FT_NEXT_USHORT( p );
328 GXV_TRACE((
"type5: nonzero value 0x%04x in unused flags\n",
330 gxv_just_check_max_gid( glyph,
"type5:glyph", gxvalid );
332 gxvalid->subtable_length = (FT_ULong)( p - table );
338 gxv_just_actSubrecord_validate( FT_Bytes table,
340 GXV_Validator gxvalid )
343 FT_UShort actionClass;
344 FT_UShort actionType;
345 FT_ULong actionLength;
348 GXV_NAME_ENTER(
"just actSubrecord" );
350 GXV_LIMIT_CHECK( 2 + 2 + 4 );
351 actionClass = FT_NEXT_USHORT( p );
352 actionType = FT_NEXT_USHORT( p );
353 actionLength = FT_NEXT_ULONG( p );
356 if ( ( actionClass & 0xFF80 ) != 0 )
357 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA );
359 if ( actionType == 0 )
360 gxv_just_actSubrecord_type0_validate( p, limit, gxvalid );
361 else if ( actionType == 1 )
362 gxv_just_actSubrecord_type1_validate( p, limit, gxvalid );
363 else if ( actionType == 2 )
364 gxv_just_actSubrecord_type2_validate( p, limit, gxvalid );
365 else if ( actionType == 3 )
367 else if ( actionType == 4 )
368 gxv_just_actSubrecord_type4_validate( p, limit, gxvalid );
369 else if ( actionType == 5 )
370 gxv_just_actSubrecord_type5_validate( p, limit, gxvalid );
374 gxvalid->subtable_length = actionLength;
381 gxv_just_pcActionRecord_validate( FT_Bytes table,
383 GXV_Validator gxvalid )
386 FT_ULong actionCount;
390 GXV_LIMIT_CHECK( 4 );
391 actionCount = FT_NEXT_ULONG( p );
392 GXV_TRACE((
"actionCount = %lu\n", actionCount ));
394 for ( i = 0; i < actionCount; i++ )
396 gxv_just_actSubrecord_validate( p, limit, gxvalid );
397 p += gxvalid->subtable_length;
400 gxvalid->subtable_length = (FT_ULong)( p - table );
407 gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph,
408 GXV_LookupValueCPtr value_p,
409 GXV_Validator gxvalid )
413 if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) )
414 GXV_JUST_DATA( pc_offset_max ) = value_p->u;
415 if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) )
416 GXV_JUST_DATA( pc_offset_min ) = value_p->u;
421 gxv_just_pcLookupTable_validate( FT_Bytes table,
423 GXV_Validator gxvalid )
428 GXV_NAME_ENTER(
"just pcLookupTable" );
429 GXV_JUST_DATA( pc_offset_max ) = 0x0000;
430 GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU;
432 gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
433 gxvalid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate;
435 gxv_LookupTable_validate( p, limit, gxvalid );
444 gxv_just_postcompTable_validate( FT_Bytes table,
446 GXV_Validator gxvalid )
451 GXV_NAME_ENTER(
"just postcompTable" );
453 gxv_just_pcLookupTable_validate( p, limit, gxvalid );
454 p += gxvalid->subtable_length;
456 gxv_just_pcActionRecord_validate( p, limit, gxvalid );
457 p += gxvalid->subtable_length;
459 gxvalid->subtable_length = (FT_ULong)( p - table );
466 gxv_just_classTable_entry_validate(
469 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
472 GXV_Validator gxvalid )
474#ifdef GXV_LOAD_UNUSED_VARS
477 FT_UShort dontAdvance;
479 FT_UShort currentClass;
483 FT_UNUSED( glyphOffset_p );
486 FT_UNUSED( gxvalid );
488#ifndef GXV_LOAD_UNUSED_VARS
491 setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
492 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
493 markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F );
494 currentClass = (FT_UShort)( flags & 0x7F );
500 gxv_just_justClassTable_validate ( FT_Bytes table,
502 GXV_Validator gxvalid )
507 FT_ULong subFeatureFlags;
510 GXV_NAME_ENTER(
"just justClassTable" );
512 GXV_LIMIT_CHECK( 2 + 2 + 4 );
513 length = FT_NEXT_USHORT( p );
514 coverage = FT_NEXT_USHORT( p );
515 subFeatureFlags = FT_NEXT_ULONG( p );
517 GXV_TRACE((
" justClassTable: coverage = 0x%04x ", coverage ));
518 if ( ( coverage & 0x4000 ) == 0 )
519 GXV_TRACE((
"ascending\n" ));
521 GXV_TRACE((
"descending\n" ));
523 if ( subFeatureFlags )
524 GXV_TRACE((
" justClassTable: nonzero value (0x%08lx)"
525 " in unused subFeatureFlags\n", subFeatureFlags ));
527 gxvalid->statetable.optdata = NULL;
528 gxvalid->statetable.optdata_load_func = NULL;
529 gxvalid->statetable.subtable_setup_func = NULL;
530 gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE;
531 gxvalid->statetable.entry_validate_func =
532 gxv_just_classTable_entry_validate;
534 gxv_StateTable_validate( p, table + length, gxvalid );
543 gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph,
544 GXV_LookupValueCPtr value_p,
545 GXV_Validator gxvalid )
549 if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) )
550 GXV_JUST_DATA( wdc_offset_max ) = value_p->u;
551 if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) )
552 GXV_JUST_DATA( wdc_offset_min ) = value_p->u;
557 gxv_just_justData_lookuptable_validate( FT_Bytes table,
559 GXV_Validator gxvalid )
564 GXV_JUST_DATA( wdc_offset_max ) = 0x0000;
565 GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU;
567 gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
568 gxvalid->lookupval_func = gxv_just_wdcTable_LookupValue_validate;
570 gxv_LookupTable_validate( p, limit, gxvalid );
582 gxv_just_justData_validate( FT_Bytes table,
584 GXV_Validator gxvalid )
590 FT_UShort justClassTableOffset;
591 FT_UShort wdcTableOffset;
592 FT_UShort pcTableOffset;
595 GXV_ODTECT( 4, odtect );
598 GXV_NAME_ENTER(
"just justData" );
600 GXV_ODTECT_INIT( odtect );
601 GXV_LIMIT_CHECK( 2 + 2 + 2 );
602 justClassTableOffset = FT_NEXT_USHORT( p );
603 wdcTableOffset = FT_NEXT_USHORT( p );
604 pcTableOffset = FT_NEXT_USHORT( p );
606 GXV_TRACE((
" (justClassTableOffset = 0x%04x)\n", justClassTableOffset ));
607 GXV_TRACE((
" (wdcTableOffset = 0x%04x)\n", wdcTableOffset ));
608 GXV_TRACE((
" (pcTableOffset = 0x%04x)\n", pcTableOffset ));
610 gxv_just_justData_lookuptable_validate( p, limit, gxvalid );
611 gxv_odtect_add_range( p, gxvalid->subtable_length,
612 "just_LookupTable", odtect );
614 if ( wdcTableOffset )
616 gxv_just_widthDeltaClusters_validate(
617 gxvalid->root->base + wdcTableOffset, limit, gxvalid );
618 gxv_odtect_add_range( gxvalid->root->base + wdcTableOffset,
619 gxvalid->subtable_length,
"just_wdcTable", odtect );
624 gxv_just_postcompTable_validate( gxvalid->root->base + pcTableOffset,
626 gxv_odtect_add_range( gxvalid->root->base + pcTableOffset,
627 gxvalid->subtable_length,
"just_pcTable", odtect );
630 if ( justClassTableOffset )
632 gxv_just_justClassTable_validate(
633 gxvalid->root->base + justClassTableOffset, limit, gxvalid );
634 gxv_odtect_add_range( gxvalid->root->base + justClassTableOffset,
635 gxvalid->subtable_length,
"just_justClassTable",
639 gxv_odtect_validate( odtect, gxvalid );
646 gxv_just_validate( FT_Bytes table,
648 FT_Validator ftvalid )
653 GXV_ValidatorRec gxvalidrec;
654 GXV_Validator gxvalid = &gxvalidrec;
655 GXV_just_DataRec justrec;
656 GXV_just_Data just = &justrec;
660 FT_UShort horizOffset;
661 FT_UShort vertOffset;
663 GXV_ODTECT( 3, odtect );
666 GXV_ODTECT_INIT( odtect );
668 gxvalid->root = ftvalid;
669 gxvalid->table_data = just;
670 gxvalid->face = face;
672 FT_TRACE3((
"validating `just' table\n" ));
675 limit = gxvalid->root->limit;
677 GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
678 version = FT_NEXT_ULONG( p );
679 format = FT_NEXT_USHORT( p );
680 horizOffset = FT_NEXT_USHORT( p );
681 vertOffset = FT_NEXT_USHORT( p );
682 gxv_odtect_add_range( table, (FT_ULong)( p - table ),
683 "just header", odtect );
687 GXV_TRACE((
" (version = 0x%08lx)\n", version ));
688 if ( version != 0x00010000UL )
692 GXV_TRACE((
" (format = 0x%04x)\n", format ));
693 if ( format != 0x0000 )
696 GXV_TRACE((
" (horizOffset = %d)\n", horizOffset ));
697 GXV_TRACE((
" (vertOffset = %d)\n", vertOffset ));
701 if ( 0 < horizOffset )
703 gxv_just_justData_validate( table + horizOffset, limit, gxvalid );
704 gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length,
705 "horizJustData", odtect );
708 if ( 0 < vertOffset )
710 gxv_just_justData_validate( table + vertOffset, limit, gxvalid );
711 gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length,
712 "vertJustData", odtect );
715 gxv_odtect_validate( odtect, gxvalid );