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/otlcommn.c | 940 ++++++++++++++++++++++++ 1 file changed, 940 insertions(+) create mode 100644 nx-X11/extras/freetype2/src/otlayout/otlcommn.c (limited to 'nx-X11/extras/freetype2/src/otlayout/otlcommn.c') diff --git a/nx-X11/extras/freetype2/src/otlayout/otlcommn.c b/nx-X11/extras/freetype2/src/otlayout/otlcommn.c new file mode 100644 index 000000000..742ff5b36 --- /dev/null +++ b/nx-X11/extras/freetype2/src/otlayout/otlcommn.c @@ -0,0 +1,940 @@ +/***************************************************************************/ +/* */ +/* otlcommn.c */ +/* */ +/* OpenType layout support, common tables (body). */ +/* */ +/* Copyright 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include "otlayout.h" + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** COVERAGE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_coverage_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p; + OTL_UInt format; + + + if ( table + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt count = OTL_NEXT_USHORT( p ); + + + if ( p + count * 2 >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check glyph indices */ + } + break; + + case 2: + { + OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p ); + OTL_UInt start, end, start_cover, total = 0, last = 0; + + + if ( p + num_ranges * 6 >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( n = 0; n < num_ranges; n++ ) + { + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + start_cover = OTL_NEXT_USHORT( p ); + + if ( start > end || start_cover != total ) + OTL_INVALID_DATA; + + if ( n > 0 && start <= last ) + OTL_INVALID_DATA; + + total += end - start + 1; + last = end; + } + } + break; + + default: + OTL_INVALID_FORMAT; + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_coverage_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table; + OTL_UInt format = OTL_NEXT_USHORT( p ); + OTL_UInt count = OTL_NEXT_USHORT( p ); + OTL_UInt result = 0; + + + switch ( format ) + { + case 1: + return count; + + case 2: + { + OTL_UInt start, end; + + + for ( ; count > 0; count-- ) + { + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + p += 2; /* skip start_index */ + + result += end - start + 1; + } + } + break; + + default: + ; + } + + return result; + } + + + OTL_LOCALDEF( OTL_Int ) + otl_coverage_get_index( OTL_Bytes table, + OTL_UInt glyph_index ) + { + OTL_Bytes p = table; + OTL_UInt format = OTL_NEXT_USHORT( p ); + OTL_UInt count = OTL_NEXT_USHORT( p ); + + + switch ( format ) + { + case 1: + { + OTL_UInt min = 0, max = count, mid, gindex; + + + table += 4; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 2 * mid; + gindex = OTL_PEEK_USHORT( p ); + + if ( glyph_index == gindex ) + return (OTL_Int)mid; + + if ( glyph_index < gindex ) + max = mid; + else + min = mid + 1; + } + } + break; + + case 2: + { + OTL_UInt min = 0, max = count, mid; + OTL_UInt start, end, delta, start_cover; + + + table += 4; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 6 * mid; + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + + if ( glyph_index < start ) + max = mid; + else if ( glyph_index > end ) + min = mid + 1; + else + return (OTL_Int)( glyph_index + OTL_NEXT_USHORT( p ) - start ); + } + } + break; + + default: + ; + } + + return -1; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CLASS DEFINITION TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_class_definition_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt format; + + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + format = OTL_NEXT_USHORT( p ); + switch ( format ) + { + case 1: + { + OTL_UInt count, start = OTL_NEXT_USHORT( p ); + + + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + count = OTL_NEXT_USHORT( p ); + + if ( p + count * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check glyph indices */ + } + break; + + case 2: + { + OTL_UInt n, num_ranges = OTL_NEXT_USHORT( p ); + OTL_UInt start, end, value, last = 0; + + + if ( p + num_ranges * 6 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( n = 0; n < num_ranges; n++ ) + { + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + value = OTL_NEXT_USHORT( p ); /* ignored */ + + if ( start > end || ( n > 0 && start <= last ) ) + OTL_INVALID_DATA; + + last = end; + } + } + break; + + default: + OTL_INVALID_FORMAT; + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_class_definition_get_value( OTL_Bytes table, + OTL_UInt glyph_index ) + { + OTL_Bytes p = table; + OTL_UInt format = OTL_NEXT_USHORT( p ); + + + switch ( format ) + { + case 1: + { + OTL_UInt start = OTL_NEXT_USHORT( p ); + OTL_UInt count = OTL_NEXT_USHORT( p ); + OTL_UInt idx = (OTL_UInt)( glyph_index - start ); + + + if ( idx < count ) + { + p += 2 * idx; + return OTL_PEEK_USHORT( p ); + } + } + break; + + case 2: + { + OTL_UInt count = OTL_NEXT_USHORT( p ); + OTL_UInt min = 0, max = count, mid, gindex; + + + table += 4; + while ( min < max ) + { + mid = ( min + max ) >> 1; + p = table + 6 * mid; + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + + if ( glyph_index < start ) + max = mid; + else if ( glyph_index > end ) + min = mid + 1; + else + return OTL_PEEK_USHORT( p ); + } + } + break; + + default: + ; + } + + return 0; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** DEVICE TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_device_table_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt start, end, count, format, count; + + + if ( p + 8 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + format = OTL_NEXT_USHORT( p ); + + if ( format < 1 || format > 3 || end < start ) + OTL_INVALID_DATA; + + count = (OTL_UInt)( end - start + 1 ); + + if ( p + ( ( 1 << format ) * count ) / 8 > valid->limit ) + OTL_INVALID_TOO_SHORT; + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_device_table_get_start( OTL_Bytes table ) + { + OTL_Bytes p = table; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_device_table_get_end( OTL_Bytes table ) + { + OTL_Bytes p = table + 2; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Int ) + otl_device_table_get_delta( OTL_Bytes table, + OTL_UInt size ) + { + OTL_Bytes p = table; + OTL_Int result = 0; + OTL_UInt start, end, format, idx, value; + + + start = OTL_NEXT_USHORT( p ); + end = OTL_NEXT_USHORT( p ); + format = OTL_NEXT_USHORT( p ); + + if ( size >= start && size <= end ) + { + /* we could do that with clever bit operations, but a switch is */ + /* much simpler to understand and maintain */ + /* */ + switch ( format ) + { + case 1: + idx = (OTL_UInt)( ( size - start ) * 2 ); + p += idx / 16; + value = OTL_PEEK_USHORT( p ); + shift = idx & 15; + result = (OTL_Short)( value << shift ) >> ( 14 - shift ); + + break; + + case 2: + idx = (OTL_UInt)( ( size - start ) * 4 ); + p += idx / 16; + value = OTL_PEEK_USHORT( p ); + shift = idx & 15; + result = (OTL_Short)( value << shift ) >> ( 12 - shift ); + + break; + + case 3: + idx = (OTL_UInt)( ( size - start ) * 8 ); + p += idx / 16; + value = OTL_PEEK_USHORT( p ); + shift = idx & 15; + result = (OTL_Short)( value << shift ) >> ( 8 - shift ); + + break; + + default: + ; + } + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_lookup_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt num_tables; + + + if ( table + 6 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + p += 4; + num_tables = OTL_NEXT_USHORT( p ); + + if ( p + num_tables * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_tables > 0; num_tables-- ) + { + offset = OTL_NEXT_USHORT( p ); + + if ( table + offset >= valid->limit ) + OTL_INVALID_OFFSET; + } + + /* XXX: check sub-tables? */ + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lookup_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table + 4; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_get_table( OTL_Bytes table, + OTL_UInt idx ) + { + OTL_Bytes p, result = NULL; + OTL_UInt count; + + + p = table + 4; + count = OTL_NEXT_USHORT( p ); + if ( idx < count ) + { + p += idx * 2; + result = table + OTL_PEEK_USHORT( p ); + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_lookup_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table, q; + OTL_UInt num_lookups, offset; + + + if ( p + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + num_lookups = OTL_NEXT_USHORT( p ); + + if ( p + num_lookups * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_lookups > 0; num_lookups-- ) + { + offset = OTL_NEXT_USHORT( p ); + + otl_lookup_validate( table + offset, valid ); + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lookup_list_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_list_get_lookup( OTL_Bytes table, + OTL_UInt idx ) + { + OTL_Bytes p, result = 0; + OTL_UInt count; + + + p = table; + count = OTL_NEXT_USHORT( p ); + if ( idx < count ) + { + p += idx * 2; + result = table + OTL_PEEK_USHORT( p ); + } + + return result; + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_lookup_list_get_table( OTL_Bytes table, + OTL_UInt lookup_index, + OTL_UInt table_index ) + { + OTL_Bytes result = NULL; + + + result = otl_lookup_list_get_lookup( table, lookup_index ); + if ( result ) + result = otl_lookup_get_table( result, table_index ); + + return result; + } + + + OTL_LOCALDEF( void ) + otl_lookup_list_foreach( OTL_Bytes table, + OTL_ForeachFunc func, + OTL_Pointer func_data ) + { + OTL_Bytes p = table; + OTL_UInt count = OTL_NEXT_USHORT( p ); + + + for ( ; count > 0; count-- ) + func( table + OTL_NEXT_USHORT( p ), func_data ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURES *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_feature_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt feat_params, num_lookups; + + + if ( p + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + feat_params = OTL_NEXT_USHORT( p ); /* ignored */ + num_lookups = OTL_NEXT_USHORT( p ); + + if ( p + num_lookups * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check lookup indices */ + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_feature_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table + 4; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_feature_get_lookups( OTL_Bytes table, + OTL_UInt start, + OTL_UInt count, + OTL_UInt *lookups ) + { + OTL_Bytes p; + OTL_UInt num_features, result = 0; + + + p = table + 4; + num_features = OTL_NEXT_USHORT( p ); + + p += start * 2; + + for ( ; count > 0 && start < num_features; count--, start++ ) + { + lookups[0] = OTL_NEXT_USHORT(p); + lookups++; + result++; + } + + return result; + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** FEATURE LIST *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + OTL_LOCALDEF( void ) + otl_feature_list_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt num_features, offset; + + + if ( table + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + num_features = OTL_NEXT_USHORT( p ); + + if ( p + num_features * 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_features > 0; num_features-- ) + { + p += 4; /* skip tag */ + offset = OTL_NEXT_USHORT( p ); + + otl_feature_table_validate( table + offset, valid ); + } + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_feature_list_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_Bytes ) + otl_feature_list_get_feature( OTL_Bytes table, + OTL_UInt idx ) + { + OTL_Bytes p, result = NULL; + OTL_UInt count; + + + p = table; + count = OTL_NEXT_USHORT( p ); + + if ( idx < count ) + { + p += idx * 2; + result = table + OTL_PEEK_USHORT( p ); + } + + return result; + } + + + OTL_LOCALDEF( void ) + otl_feature_list_foreach( OTL_Bytes table, + OTL_ForeachFunc func, + OTL_Pointer func_data ) + { + OTL_Bytes p; + OTL_UInt count; + + + p = table; + count = OTL_NEXT_USHORT( p ); + + for ( ; count > 0; count-- ) + func( table + OTL_NEXT_USHORT( p ), func_data ); + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LANGUAGE SYSTEM *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_lang_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt lookup_order; + OTL_UInt req_feature; + OTL_UInt num_features; + + + if ( table + 6 >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + lookup_order = OTL_NEXT_USHORT( p ); + req_feature = OTL_NEXT_USHORT( p ); + num_features = OTL_NEXT_USHORT( p ); + + /* XXX: check req_feature if not 0xFFFFU */ + + if ( p + 2 * num_features >= valid->limit ) + OTL_INVALID_TOO_SHORT; + + /* XXX: check features indices! */ + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lang_get_count( OTL_Bytes table ) + { + OTL_Bytes p = table + 4; + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lang_get_req_feature( OTL_Bytes table ) + { + OTL_Bytes p = table + 2; + + + return OTL_PEEK_USHORT( p ); + } + + + OTL_LOCALDEF( OTL_UInt ) + otl_lang_get_features( OTL_Bytes table, + OTL_UInt start, + OTL_UInt count, + OTL_UInt *features ) + { + OTL_Bytes p = table + 4; + OTL_UInt num_features = OTL_NEXT_USHORT( p ); + OTL_UInt result = 0; + + + p += start * 2; + + for ( ; count > 0 && start < num_features; start++, count-- ) + { + features[0] = OTL_NEXT_USHORT( p ); + features++; + result++; + } + + return result; + } + + + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SCRIPTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + OTL_LOCALDEF( void ) + otl_script_validate( OTL_Bytes table, + OTL_Validator valid ) + { + OTL_UInt default_lang; + OTL_Bytes p = table; + + + if ( table + 4 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + default_lang = OTL_NEXT_USHORT( p ); + num_langs = OTL_NEXT_USHORT( p ); + + if ( default_lang != 0 ) + { + if ( table + default_lang >= valid->limit ) + OTL_INVALID_OFFSET; + } + + if ( p + num_langs * 6 >= valid->limit ) + OTL_INVALID_OFFSET; + + for ( ; num_langs > 0; num_langs-- ) + { + OTL_UInt offset; + + + p += 4; /* skip tag */ + offset = OTL_NEXT_USHORT( p ); + + otl_lang_validate( table + offset, valid ); + } + } + + + OTL_LOCALDEF( void ) + otl_script_list_validate( OTL_Bytes list, + OTL_Validator valid ) + { + OTL_UInt num_scripts; + OTL_Bytes p = list; + + + if ( list + 2 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + num_scripts = OTL_NEXT_USHORT( p ); + + if ( p + num_scripts * 6 > valid->limit ) + OTL_INVALID_TOO_SHORT; + + for ( ; num_scripts > 0; num_scripts-- ) + { + OTL_UInt offset; + + + p += 4; /* skip tag */ + offset = OTL_NEXT_USHORT( p ); + + otl_script_table_validate( list + offset, valid ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** LOOKUP LISTS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otl_lookup_table_validate( OTL_Bytes table, + OTL_UInt type_count, + OTL_ValidateFunc* type_funcs, + OTL_Validator valid ) + { + OTL_Bytes p = table; + OTL_UInt lookup_type, lookup_flag, count; + OTL_ValidateFunc validate; + + OTL_CHECK( 6 ); + lookup_type = OTL_NEXT_USHORT( p ); + lookup_flag = OTL_NEXT_USHORT( p ); + count = OTL_NEXT_USHORT( p ); + + if ( lookup_type == 0 || lookup_type >= type_count ) + OTL_INVALID_DATA; + + validate = type_funcs[ lookup_type - 1 ]; + + OTL_CHECK( 2*count ); + for ( ; count > 0; count-- ) + validate( table + OTL_NEXT_USHORT( p ), valid ); + } + + + OTL_LOCALDEF( void ) + otl_lookup_list_validate( OTL_Bytes table, + OTL_UInt type_count, + OTL_ValidateFunc* type_funcs, + 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_lookup_table_validate( table + OTL_NEXT_USHORT( p ), + type_count, type_funcs, valid ); + } + +/* END */ -- cgit v1.2.3