From f4092abdf94af6a99aff944d6264bc1284e8bdd4 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Mon, 10 Oct 2011 17:43:39 +0200 Subject: Imported nx-X11-3.1.0-1.tar.gz Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository --- nx-X11/extras/freetype2/src/otlayout/otlgpos.c | 980 +++++++++++++++++++++++++ 1 file changed, 980 insertions(+) create mode 100644 nx-X11/extras/freetype2/src/otlayout/otlgpos.c (limited to 'nx-X11/extras/freetype2/src/otlayout/otlgpos.c') diff --git a/nx-X11/extras/freetype2/src/otlayout/otlgpos.c b/nx-X11/extras/freetype2/src/otlayout/otlgpos.c new file mode 100644 index 000000000..01942d7f0 --- /dev/null +++ b/nx-X11/extras/freetype2/src/otlayout/otlgpos.c @@ -0,0 +1,980 @@ +#include "otlgpos.h" +#include "otlcommn.h" + + /* forward declaration */ + static OTL_ValidateFunc otl_gpos_validate_funcs[]; + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** VALUE RECORDS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static OTL_UInt + otl_value_length( OTL_UInt format ) + { + FT_UInt count; + + count = (( format & 0xAA ) >> 1) + ( format & 0x55 ); + count = (( count & 0xCC ) >> 2) + ( count & 0x33 ); + count = (( count & 0xF0 ) >> 4) + ( count & 0x0F ); + + return count; + } + + + static void + otl_value_validate( OTL_Bytes table, + OTL_Bytes pos_table, + OTL_UInt format, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, device; + + if ( format >= 0x100U ) + OTL_INVALID_DATA; + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + OTL_CHECK( 2 ); + p += 2; + } + + format >>= 1; + } + + for ( count = 4; count > 0; count-- ) + { + if ( format & 1 ) + { + OTL_CHECK( 2 ); + device = OTL_NEXT_USHORT( p ); + if ( device ) + otl_device_table_validate( pos_table + device, valid ); + } + format >>= 1; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** ANCHORS *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_anchor_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 6 ); + format = OTL_NEXT_USHORT( p ); + p += 4; + + switch ( format ) + { + case 1: + break; + + case 2: + OTL_CHECK( 2 ); /* anchor point */ + break; + + case 3: + { + OTL_UInt x_device, y_device; + + OTL_CHECK( 4 ); + x_device = OTL_NEXT_USHORT( p ); + y_device = OTL_NEXT_USHORT( p ); + + if ( x_device ) + otl_device_table_validate( table + x_device, valid ); + + if ( y_device ) + otl_device_table_validate( table + y_device, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** MARK ARRAY *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_mark_array_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + + count = OTL_NEXT_USHORT( p ); + OTL_CHECK( count * 4 ); + for ( ; count > 0; count-- ) + { + p += 2; /* ignore class index */ + otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 1 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gpos_lookup1_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + FT_UInt coverage, value_format; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + value_format = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + otl_value_validate( p, table, value_format, valid ); + } + break; + + case 2: + { + FT_UInt coverage, value_format, count, len; + + OTL_CHECK( 6 ); + coverage = OTL_NEXT_USHORT( p ); + value_format = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + len = otl_value_length( value_format ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count * len ); + for ( ; count > 0; count-- ) + { + otl_value_validate( p, table, value_format, valid ); + p += len; + } + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 2 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static otl_gpos_pairset_validate( OTL_Bytes table, + OTL_Bytes pos_table, + OTL_UInt format1, + OTL_UInt format2, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt len1, len2, count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + len1 = otl_value_length( format1 ); + len2 = otl_value_length( format2 ); + + OTL_CHECK( count * (len1+len2+2) ); + for ( ; count > 0; count-- ) + { + p += 2; /* ignore glyph id */ + otl_value_validate( p, pos_table, format1, valid ); + p += len1; + + otl_value_validate( p, pos_table, format2, valid ); + p += len2; + } + } + + static void + otl_gpos_lookup2_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, value1, value2, count; + + OTL_CHECK( 8 ); + coverage = OTL_NEXT_USHORT( p ); + value1 = OTL_NEXT_USHORT( p ); + value2 = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + { + otl_gpos_pairset_validate( table + OTL_NEXT_USHORT( p ), + table, value1, value2, valid ); + } + } + break; + + case 2: + { + OTL_UInt coverage, value1, value2, class1, class2, count1, count2; + OTL_UInt len1, len2; + + OTL_CHECK( 14 ); + coverage = OTL_NEXT_USHORT( p ); + value1 = OTL_NEXT_USHORT( p ); + value2 = OTL_NEXT_USHORT( p ); + class1 = OTL_NEXT_USHORT( p ); + class2 = OTL_NEXT_USHORT( p ); + count1 = OTL_NEXT_USHORT( p ); + count2 = OTL_NEXT_USHORT( p ); + + len1 = otl_value_length( value1 ); + len2 = otl_value_length( value2 ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count1*count2*(len1+len2) ); + for ( ; count1 > 0; count1-- ) + { + for ( ; count2 > 0; count2-- ) + { + otl_value_validate( p, table, value1, valid ); + p += len1; + + otl_value_validate( p, table, value2, valid ); + p += len2; + } + } + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 3 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gpos_lookup3_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, count, anchor1, anchor2; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*4 ); + for ( ; count > 0; count-- ) + { + anchor1 = OTL_NEXT_USHORT( p ); + anchor2 = OTL_NEXT_USHORT( p ); + + if ( anchor1 ) + otl_anchor_validate( table + anchor1, valid ); + + if ( anchor2 ) + otl_anchor_validate( table + anchor2, valid ); + } + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 4 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_base_array_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*class_count*2 ); + for ( ; count > 0; count-- ) + for ( count2 = class_count; count2 > 0; count2-- ) + otl_anchor_validate( table + OTL_NEXT_USHORT( p ) ); + } + + + static void + otl_gpos_lookup4_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt mark_coverage, base_coverage, class_count; + OTL_UInt mark_array, base_array; + + OTL_CHECK( 10 ); + mark_coverage = OTL_NEXT_USHORT( p ); + base_coverage = OTL_NEXT_USHORT( p ); + class_count = OTL_NEXT_USHORT( p ); + mark_array = OTL_NEXT_USHORT( p ); + base_array = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + mark_coverage, valid ); + otl_coverage_validate( table + base_coverage, valid ); + + otl_mark_array_validate( table + mark_array, valid ); + otl_base_array_validate( table, class_count, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 5 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_liga_attach_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*class_count*2 ); + for ( ; count > 0; count-- ) + for ( count2 = class_count; class_count > 0; class_count-- ) + otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_liga_array_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_liga_attach_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gpos_lookup5_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt mark_coverage, lig_coverage, class_count; + OTL_UInt mar_array, lig_array; + + OTL_CHECK( 10 ); + mark_coverage = OTL_NEXT_USHORT( p ); + liga_coverage = OTL_NEXT_USHORT( p ); + class_count = OTL_NEXT_USHORT( p ); + mark_array = OTL_NEXT_USHORT( p ); + liga_array = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + mark_coverage, valid ); + otl_coverage_validate( table + liga_coverage, valid ); + + otl_mark_array_validate( table + mark_array, valid ); + otl_liga_array_validate( table + liga_array, class_count, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 6 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + static void + otl_mark2_array_validate( OTL_Bytes table, + OTL_UInt class_count, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count, count2; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*class_count*2 ); + for ( ; count > 0; count-- ) + for ( count2 = class_count; class_count > 0; class_count-- ) + otl_anchor_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gpos_lookup6_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage1, coverage2, class_count, array1, array2; + + OTL_CHECK( 10 ); + coverage1 = OTL_NEXT_USHORT( p ); + coverage2 = OTL_NEXT_USHORT( p ); + class_count = OTL_NEXT_USHORT( p ); + array1 = OTL_NEXT_USHORT( p ); + array2 = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage1, valid ); + otl_coverage_validate( table + coverage2, valid ); + + otl_mark_array_validate( table + array1, valid ); + otl_mark2_array_validate( table + array2, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 7 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_pos_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt glyph_count, pos_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + pos_count = OTL_NEXT_USHORT( p ); + + if ( glyph_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( (glyph_count-1)*2 + pos_count*4 ); + + /* XXX: check glyph indices and pos lookups */ + } + + + static void + otl_pos_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid ); + } + + + + static void + otl_pos_class_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt glyph_count, pos_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + pos_count = OTL_NEXT_USHORT( p ); + + if ( glyph_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( (glyph_count-1)*2 + pos_count*4 ); + + /* XXX: check glyph indices and pos lookups */ + } + + + static void + otl_pos_class_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_pos_rule_validate( table + OTL_NEXT_USHORT(p), valid ); + } + + + static void + otl_gpos_lookup7_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + break; + + case 2: + { + OTL_UInt coverage, class_def, count; + + OTL_CHECK( 6 ); + coverage = OTL_NEXT_USHORT( p ); + class_def = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate ( table + coverage, valid ); + otl_class_definition_validate( table + class_def, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_ + } + break; + + case 3: + { + OTL_UInt glyph_count, pos_count; + + OTL_CHECK( 4 ); + glyph_count = OTL_NEXT_USHORT( p ); + pos_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( glyph_count*2 + pos_count*4 ); + for ( ; glyph_count > 0; glyph_count ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + /* XXX: check pos lookups */ + } + break; + + default: + OTL_INVALID_DATA; + } + } + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 8 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_chain_pos_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt back_count, input_count, ahead_count, pos_count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( back_count*2 + 2 ); + p += back_count*2; + + input_count = OTL_NEXT_USHORT( p ); + if ( input_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( input_count*2 ); + p += (input_count-1)*2; + + ahead_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( ahead_count*2 + 2 ); + p += ahead_count*2; + + pos_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( pos_count*4 ); + } + + + static void + otl_chain_pos_rule_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_pos_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + + static void + otl_chain_pos_class_rule_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt back_count, input_count, ahead_count, pos_count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( back_count*2 + 2 ); + p += back_count*2; + + input_count = OTL_NEXT_USHORT( p ); + if ( input_count == 0 ) + OTL_INVALID_DATA; + + OTL_CHECK( input_count*2 ); + p += (input_count-1)*2; + + ahead_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( ahead_count*2 + 2 ); + p += ahead_count*2; + + pos_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( pos_count*4 ); + } + + + static void + otl_chain_pos_class_set_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt count; + + OTL_CHECK( 2 ); + count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + otl_chain_pos_class_rule_validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + static void + otl_gpos_lookup8_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt coverage, count; + + OTL_CHECK( 4 ); + coverage = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_chain_pos_rule_set_validate( table + OTL_NEXT_USHORT( p ), + valid ); + } + break; + + case 2: + { + OTL_UInt coverage, back_class, input_class, ahead_class, count; + + OTL_CHECK( 10 ); + coverage = OTL_NEXT_USHORT( p ); + back_class = OTL_NEXT_USHORT( p ); + input_class = OTL_NEXT_USHORT( p ); + ahead_class = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + otl_coverage_validate( table + coverage, valid ); + + otl_class_definition_validate( table + back_class, valid ); + otl_class_definition_validate( table + input_class, valid ); + otl_class_definition_validate( table + ahead_class, valid ); + + OTL_CHECK( count*2 ); + for ( ; count > 0; count-- ) + otl_chain_pos_class_set_validate( table + OTL_NEXT_USHORT( p ), + valid ); + } + break; + + case 3: + { + OTL_UInt back_count, input_count, ahead_count, pos_count, count; + + OTL_CHECK( 2 ); + back_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*back_count+2 ); + for ( count = back_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + input_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*input_count+2 ); + for ( count = input_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + ahead_count = OTL_NEXT_USHORT( p ); + + OTL_CHECK( 2*ahead_count+2 ); + for ( count = ahead_count; count > 0; count-- ) + otl_coverage_validate( table + OTL_NEXT_USHORT( p ), valid ); + + pos_count = OTL_NEXT_USHORT( p ); + OTL_CHECK( pos_count*4 ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS LOOKUP TYPE 9 *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + static void + otl_gpos_lookup9_validate( OTL_Bytes table, + OTL_Valid valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + OTL_CHECK( 2 ); + format = OTL_NEXT_USHORT( p ); + switch (format) + { + case 1: + { + OTL_UInt lookup_type, lookup_offset; + OTL_ValidateFunc validate; + + OTL_CHECK( 6 ); + lookup_type = OTL_NEXT_USHORT( p ); + lookup_offset = OTL_NEXT_ULONG( p ); + + if ( lookup_type == 0 || lookup_type >= 9 ) + OTL_INVALID_DATA; + + validate = otl_gpos_validate_funcs[ lookup_type-1 ]; + validate( table + lookup_offset, valid ); + } + break; + + default: + OTL_INVALID_DATA; + } + } + + static OTL_ValidateFunc otl_gpos_validate_funcs[ 9 ] = + { + otl_gpos_lookup1_validate, + otl_gpos_lookup2_validate, + otl_gpos_lookup3_validate, + otl_gpos_lookup4_validate, + otl_gpos_lookup5_validate, + otl_gpos_lookup6_validate, + otl_gpos_lookup7_validate, + otl_gpos_lookup8_validate, + otl_gpos_lookup9_validate, + }; + + + /************************************************************************/ + /************************************************************************/ + /***** *****/ + /***** GPOS TABLE *****/ + /***** *****/ + /************************************************************************/ + /************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_gpos_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt scripts, features, lookups; + + OTL_CHECK( 10 ); + + if ( OTL_NEXT_USHORT( p ) != 0x10000UL ) + OTL_INVALID_DATA; + + scripts = OTL_NEXT_USHORT( p ); + features = OTL_NEXT_USHORT( p ); + lookups = OTL_NEXT_USHORT( p ); + + otl_script_list_validate ( table + scripts, valid ); + otl_feature_list_validate( table + features, valid ); + + otl_lookup_list_validate( table + lookups, 9, otl_gpos_validate_funcs, + valid ); + } + \ No newline at end of file -- cgit v1.2.3