/**************************************************************************** * * otvcommn.h * * OpenType common tables validation (specification). * * Copyright (C) 2004-2019 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. * */ #ifndef OTVCOMMN_H_ #define OTVCOMMN_H_ #include #include "otvalid.h" #include FT_INTERNAL_DEBUG_H FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** VALIDATION *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct OTV_ValidatorRec_* OTV_Validator; typedef void (*OTV_Validate_Func)( FT_Bytes table, OTV_Validator otvalid ); typedef struct OTV_ValidatorRec_ { FT_Validator root; FT_UInt type_count; OTV_Validate_Func* type_funcs; FT_UInt lookup_count; FT_UInt glyph_count; FT_UInt nesting_level; OTV_Validate_Func func[3]; FT_UInt extra1; /* for passing parameters */ FT_UInt extra2; FT_Bytes extra3; #ifdef FT_DEBUG_LEVEL_TRACE FT_UInt debug_indent; const FT_String* debug_function_name[3]; #endif } OTV_ValidatorRec; #undef FT_INVALID_ #define FT_INVALID_( _error ) \ ft_validator_error( otvalid->root, FT_THROW( _error ) ) #define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ FT_Bytes _table ## _p #define OTV_OPTIONAL_TABLE32( _table ) FT_ULong _table; \ FT_Bytes _table ## _p #define OTV_OPTIONAL_OFFSET( _offset ) \ FT_BEGIN_STMNT \ _offset ## _p = p; \ _offset = FT_NEXT_USHORT( p ); \ FT_END_STMNT #define OTV_OPTIONAL_OFFSET32( _offset ) \ FT_BEGIN_STMNT \ _offset ## _p = p; \ _offset = FT_NEXT_ULONG( p ); \ FT_END_STMNT #define OTV_LIMIT_CHECK( _count ) \ FT_BEGIN_STMNT \ if ( p + (_count) > otvalid->root->limit ) \ FT_INVALID_TOO_SHORT; \ FT_END_STMNT #define OTV_SIZE_CHECK( _size ) \ FT_BEGIN_STMNT \ if ( _size > 0 && _size < table_size ) \ { \ if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ FT_INVALID_OFFSET; \ else \ { \ /* strip off `const' */ \ FT_Byte* pp = (FT_Byte*)_size ## _p; \ \ \ FT_TRACE3(( "\n" \ "Invalid offset to optional table `%s'" \ " set to zero.\n" \ "\n", #_size )); \ \ _size = pp[0] = pp[1] = 0; \ } \ } \ FT_END_STMNT #define OTV_SIZE_CHECK32( _size ) \ FT_BEGIN_STMNT \ if ( _size > 0 && _size < table_size ) \ { \ if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ FT_INVALID_OFFSET; \ else \ { \ /* strip off `const' */ \ FT_Byte* pp = (FT_Byte*)_size ## _p; \ \ \ FT_TRACE3(( "\n" \ "Invalid offset to optional table `%s'" \ " set to zero.\n" \ "\n", #_size )); \ \ _size = pp[0] = pp[1] = pp[2] = pp[3] = 0; \ } \ } \ FT_END_STMNT #define OTV_NAME_(x) #x #define OTV_NAME(x) OTV_NAME_(x) #define OTV_FUNC_(x) x##Func #define OTV_FUNC(x) OTV_FUNC_(x) #ifdef FT_DEBUG_LEVEL_TRACE #define OTV_NEST1( x ) \ FT_BEGIN_STMNT \ otvalid->nesting_level = 0; \ otvalid->func[0] = OTV_FUNC( x ); \ otvalid->debug_function_name[0] = OTV_NAME( x ); \ FT_END_STMNT #define OTV_NEST2( x, y ) \ FT_BEGIN_STMNT \ otvalid->nesting_level = 0; \ otvalid->func[0] = OTV_FUNC( x ); \ otvalid->func[1] = OTV_FUNC( y ); \ otvalid->debug_function_name[0] = OTV_NAME( x ); \ otvalid->debug_function_name[1] = OTV_NAME( y ); \ FT_END_STMNT #define OTV_NEST3( x, y, z ) \ FT_BEGIN_STMNT \ otvalid->nesting_level = 0; \ otvalid->func[0] = OTV_FUNC( x ); \ otvalid->func[1] = OTV_FUNC( y ); \ otvalid->func[2] = OTV_FUNC( z ); \ otvalid->debug_function_name[0] = OTV_NAME( x ); \ otvalid->debug_function_name[1] = OTV_NAME( y ); \ otvalid->debug_function_name[2] = OTV_NAME( z ); \ FT_END_STMNT #define OTV_INIT otvalid->debug_indent = 0 #define OTV_ENTER \ FT_BEGIN_STMNT \ otvalid->debug_indent += 2; \ FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ FT_TRACE4(( "%s table\n", \ otvalid->debug_function_name[otvalid->nesting_level] )); \ FT_END_STMNT #define OTV_NAME_ENTER( name ) \ FT_BEGIN_STMNT \ otvalid->debug_indent += 2; \ FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ FT_TRACE4(( "%s table\n", name )); \ FT_END_STMNT #define OTV_EXIT otvalid->debug_indent -= 2 #define OTV_TRACE( s ) \ FT_BEGIN_STMNT \ FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ FT_TRACE4( s ); \ FT_END_STMNT #else /* !FT_DEBUG_LEVEL_TRACE */ #define OTV_NEST1( x ) \ FT_BEGIN_STMNT \ otvalid->nesting_level = 0; \ otvalid->func[0] = OTV_FUNC( x ); \ FT_END_STMNT #define OTV_NEST2( x, y ) \ FT_BEGIN_STMNT \ otvalid->nesting_level = 0; \ otvalid->func[0] = OTV_FUNC( x ); \ otvalid->func[1] = OTV_FUNC( y ); \ FT_END_STMNT #define OTV_NEST3( x, y, z ) \ FT_BEGIN_STMNT \ otvalid->nesting_level = 0; \ otvalid->func[0] = OTV_FUNC( x ); \ otvalid->func[1] = OTV_FUNC( y ); \ otvalid->func[2] = OTV_FUNC( z ); \ FT_END_STMNT #define OTV_INIT do { } while ( 0 ) #define OTV_ENTER do { } while ( 0 ) #define OTV_NAME_ENTER( name ) do { } while ( 0 ) #define OTV_EXIT do { } while ( 0 ) #define OTV_TRACE( s ) do { } while ( 0 ) #endif /* !FT_DEBUG_LEVEL_TRACE */ #define OTV_RUN otvalid->func[0] /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** COVERAGE TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_Coverage_validate( FT_Bytes table, OTV_Validator otvalid, FT_Int expected_count ); /* return first covered glyph */ FT_LOCAL( FT_UInt ) otv_Coverage_get_first( FT_Bytes table ); /* return last covered glyph */ FT_LOCAL( FT_UInt ) otv_Coverage_get_last( FT_Bytes table ); /* return number of covered glyphs */ FT_LOCAL( FT_UInt ) otv_Coverage_get_count( FT_Bytes table ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CLASS DEFINITION TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_ClassDef_validate( FT_Bytes table, OTV_Validator otvalid ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** DEVICE TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_Device_validate( FT_Bytes table, OTV_Validator otvalid ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** LOOKUPS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_Lookup_validate( FT_Bytes table, OTV_Validator otvalid ); FT_LOCAL( void ) otv_LookupList_validate( FT_Bytes table, OTV_Validator otvalid ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FEATURES *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_Feature_validate( FT_Bytes table, OTV_Validator otvalid ); /* lookups must already be validated */ FT_LOCAL( void ) otv_FeatureList_validate( FT_Bytes table, FT_Bytes lookups, OTV_Validator otvalid ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** LANGUAGE SYSTEM *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_LangSys_validate( FT_Bytes table, OTV_Validator otvalid ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** SCRIPTS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( void ) otv_Script_validate( FT_Bytes table, OTV_Validator otvalid ); /* features must already be validated */ FT_LOCAL( void ) otv_ScriptList_validate( FT_Bytes table, FT_Bytes features, OTV_Validator otvalid ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** UTILITY FUNCTIONS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ #define ChainPosClassSetFunc otv_x_Ox #define ChainPosRuleSetFunc otv_x_Ox #define ChainSubClassSetFunc otv_x_Ox #define ChainSubRuleSetFunc otv_x_Ox #define JstfLangSysFunc otv_x_Ox #define JstfMaxFunc otv_x_Ox #define LigGlyphFunc otv_x_Ox #define LigatureArrayFunc otv_x_Ox #define LigatureSetFunc otv_x_Ox #define PosClassSetFunc otv_x_Ox #define PosRuleSetFunc otv_x_Ox #define SubClassSetFunc otv_x_Ox #define SubRuleSetFunc otv_x_Ox FT_LOCAL( void ) otv_x_Ox ( FT_Bytes table, OTV_Validator otvalid ); #define AlternateSubstFormat1Func otv_u_C_x_Ox #define ChainContextPosFormat1Func otv_u_C_x_Ox #define ChainContextSubstFormat1Func otv_u_C_x_Ox #define ContextPosFormat1Func otv_u_C_x_Ox #define ContextSubstFormat1Func otv_u_C_x_Ox #define LigatureSubstFormat1Func otv_u_C_x_Ox #define MultipleSubstFormat1Func otv_u_C_x_Ox FT_LOCAL( void ) otv_u_C_x_Ox( FT_Bytes table, OTV_Validator otvalid ); #define AlternateSetFunc otv_x_ux #define AttachPointFunc otv_x_ux #define ExtenderGlyphFunc otv_x_ux #define JstfGPOSModListFunc otv_x_ux #define JstfGSUBModListFunc otv_x_ux #define SequenceFunc otv_x_ux FT_LOCAL( void ) otv_x_ux( FT_Bytes table, OTV_Validator otvalid ); #define PosClassRuleFunc otv_x_y_ux_sy #define PosRuleFunc otv_x_y_ux_sy #define SubClassRuleFunc otv_x_y_ux_sy #define SubRuleFunc otv_x_y_ux_sy FT_LOCAL( void ) otv_x_y_ux_sy( FT_Bytes table, OTV_Validator otvalid ); #define ChainPosClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp #define ChainPosRuleFunc otv_x_ux_y_uy_z_uz_p_sp #define ChainSubClassRuleFunc otv_x_ux_y_uy_z_uz_p_sp #define ChainSubRuleFunc otv_x_ux_y_uy_z_uz_p_sp FT_LOCAL( void ) otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, OTV_Validator otvalid ); #define ContextPosFormat2Func otv_u_O_O_x_Onx #define ContextSubstFormat2Func otv_u_O_O_x_Onx FT_LOCAL( void ) otv_u_O_O_x_Onx( FT_Bytes table, OTV_Validator otvalid ); #define ContextPosFormat3Func otv_u_x_y_Ox_sy #define ContextSubstFormat3Func otv_u_x_y_Ox_sy FT_LOCAL( void ) otv_u_x_y_Ox_sy( FT_Bytes table, OTV_Validator otvalid ); #define ChainContextPosFormat2Func otv_u_O_O_O_O_x_Onx #define ChainContextSubstFormat2Func otv_u_O_O_O_O_x_Onx FT_LOCAL( void ) otv_u_O_O_O_O_x_Onx( FT_Bytes table, OTV_Validator otvalid ); #define ChainContextPosFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp #define ChainContextSubstFormat3Func otv_u_x_Ox_y_Oy_z_Oz_p_sp FT_LOCAL( void ) otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, OTV_Validator otvalid ); FT_LOCAL( FT_UInt ) otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ); FT_LOCAL( FT_UInt ) otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ); /* */ FT_END_HEADER #endif /* OTVCOMMN_H_ */ /* END */