📄 otvgsub.c
字号:
/***************************************************************************/
/* */
/* otvgsub.c */
/* */
/* OpenType GSUB table validation (body). */
/* */
/* Copyright 2004, 2005 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 "otvalid.h"
#include "otvcommn.h"
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_otvgsub
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 1 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* uses valid->glyph_count */
static void
otv_SingleSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "SingleSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1: /* SingleSubstFormat1 */
{
FT_Bytes Coverage;
FT_Int DeltaGlyphID;
FT_Long idx;
OTV_LIMIT_CHECK( 4 );
Coverage = table + FT_NEXT_USHORT( p );
DeltaGlyphID = FT_NEXT_SHORT( p );
otv_Coverage_validate( Coverage, valid );
idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
if ( idx < 0 )
FT_INVALID_DATA;
idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
if ( (FT_UInt)idx >= valid->glyph_count )
FT_INVALID_DATA;
}
break;
case 2: /* SingleSubstFormat2 */
{
FT_UInt Coverage, GlyphCount;
OTV_LIMIT_CHECK( 4 );
Coverage = FT_NEXT_USHORT( p );
GlyphCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
otv_Coverage_validate( table + Coverage, valid );
OTV_LIMIT_CHECK( GlyphCount * 2 );
/* Substitute */
for ( ; GlyphCount > 0; GlyphCount-- )
if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
FT_INVALID_DATA;
}
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 2 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (glyph count) */
static void
otv_MultipleSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "MultipleSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
valid->extra1 = valid->glyph_count;
OTV_NEST2( MultipleSubstFormat1, Sequence );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 3 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (glyph count) */
static void
otv_AlternateSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "AlternateSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
valid->extra1 = valid->glyph_count;
OTV_NEST2( AlternateSubstFormat1, AlternateSet );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 4 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define LigatureFunc otv_Ligature_validate
/* uses valid->glyph_count */
static void
otv_Ligature_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt LigatureGlyph, CompCount;
OTV_ENTER;
OTV_LIMIT_CHECK( 4 );
LigatureGlyph = FT_NEXT_USHORT( p );
if ( LigatureGlyph >= valid->glyph_count )
FT_INVALID_DATA;
CompCount = FT_NEXT_USHORT( p );
OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
if ( CompCount == 0 )
FT_INVALID_DATA;
CompCount--;
OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */
/* no need to check the Component glyph indices */
OTV_EXIT;
}
static void
otv_LigatureSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "LigatureSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
switch ( SubstFormat )
{
case 1:
OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
OTV_RUN( table, valid );
break;
default:
FT_INVALID_DATA;
}
OTV_EXIT;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** GSUB LOOKUP TYPE 5 *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/* sets valid->extra1 (lookup count) */
static void
otv_ContextSubst_validate( FT_Bytes table,
OTV_Validator valid )
{
FT_Bytes p = table;
FT_UInt SubstFormat;
OTV_NAME_ENTER( "ContextSubst" );
OTV_LIMIT_CHECK( 2 );
SubstFormat = FT_NEXT_USHORT( p );
OTV_TRACE(( " (format %d)\n", SubstFormat ));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -