|
|
|
@ -17,13 +17,17 @@ |
|
|
|
|
/***************************************************************************/ |
|
|
|
|
|
|
|
|
|
/***************************************************************************/ |
|
|
|
|
/* */ |
|
|
|
|
/* gxvalid is derived from both gxlayout module and otvalid module. */ |
|
|
|
|
/* Development of gxlayout was support of Information-technology Promotion */ |
|
|
|
|
/* Agency(IPA), Japan. */ |
|
|
|
|
/* Development of gxlayout is supported by the Information-technology */ |
|
|
|
|
/* Promotion Agency(IPA), Japan. */ |
|
|
|
|
/* */ |
|
|
|
|
/***************************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "gxvmorx.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/* */ |
|
|
|
|
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
|
|
|
@ -46,26 +50,36 @@ |
|
|
|
|
} GXV_morx_subtable_type2_StateOptRec, |
|
|
|
|
*GXV_morx_subtable_type2_StateOptRecData; |
|
|
|
|
|
|
|
|
|
#define GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE ( GXV_XSTATETABLE_HEADER_SIZE + 4 + 4 + 4 ) |
|
|
|
|
|
|
|
|
|
#define GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE \ |
|
|
|
|
( GXV_XSTATETABLE_HEADER_SIZE + 4 + 4 + 4 ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
gxv_morx_subtable_type2_opttable_load( FT_Bytes table, |
|
|
|
|
FT_Bytes limit, |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
{ |
|
|
|
|
FT_Bytes p = table; |
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = valid->xstatetable.optdata; |
|
|
|
|
FT_Bytes p = table; |
|
|
|
|
|
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = |
|
|
|
|
valid->xstatetable.optdata; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GXV_LIMIT_CHECK( 4 + 4 + 4 ); |
|
|
|
|
optdata->ligActionTable = FT_NEXT_ULONG( p ); |
|
|
|
|
optdata->componentTable = FT_NEXT_ULONG( p ); |
|
|
|
|
optdata->ligatureTable = FT_NEXT_ULONG( p ); |
|
|
|
|
|
|
|
|
|
GXV_TRACE(( "offset to ligActionTable=0x%08x\n", optdata->ligActionTable )); |
|
|
|
|
GXV_TRACE(( "offset to componentTable=0x%08x\n", optdata->componentTable )); |
|
|
|
|
GXV_TRACE(( "offset to ligatureTable=0x%08x\n", optdata->ligatureTable )); |
|
|
|
|
GXV_TRACE(( "offset to ligActionTable=0x%08x\n", |
|
|
|
|
optdata->ligActionTable )); |
|
|
|
|
GXV_TRACE(( "offset to componentTable=0x%08x\n", |
|
|
|
|
optdata->componentTable )); |
|
|
|
|
GXV_TRACE(( "offset to ligatureTable=0x%08x\n", |
|
|
|
|
optdata->ligatureTable )); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
gxv_morx_subtable_type2_subtable_setup( FT_ULong table_size, |
|
|
|
|
FT_ULong classTable, |
|
|
|
@ -79,7 +93,9 @@ |
|
|
|
|
FT_ULong o[6]; |
|
|
|
|
FT_ULong* l[6]; |
|
|
|
|
FT_ULong buff[7]; |
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = valid->xstatetable.optdata; |
|
|
|
|
|
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = |
|
|
|
|
valid->xstatetable.optdata; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GXV_NAME_ENTER( "subtable boundaries setup" ); |
|
|
|
@ -100,35 +116,41 @@ |
|
|
|
|
gxv_set_length_by_ulong_offset( o, l, buff, 6, table_size, valid ); |
|
|
|
|
|
|
|
|
|
GXV_TRACE(( "classTable: offset=0x%08x length=0x%08x\n", |
|
|
|
|
classTable, *classTable_length_p)); |
|
|
|
|
classTable, *classTable_length_p )); |
|
|
|
|
GXV_TRACE(( "stateArray: offset=0x%08x length=0x%08x\n", |
|
|
|
|
stateArray, *stateArray_length_p)); |
|
|
|
|
stateArray, *stateArray_length_p )); |
|
|
|
|
GXV_TRACE(( "entryTable: offset=0x%08x length=0x%08x\n", |
|
|
|
|
entryTable, *entryTable_length_p)); |
|
|
|
|
entryTable, *entryTable_length_p )); |
|
|
|
|
GXV_TRACE(( "ligActionTable: offset=0x%08x length=0x%08x\n", |
|
|
|
|
optdata->ligActionTable, |
|
|
|
|
optdata->ligActionTable_length)); |
|
|
|
|
optdata->ligActionTable, |
|
|
|
|
optdata->ligActionTable_length )); |
|
|
|
|
GXV_TRACE(( "componentTable: offset=0x%08x length=0x%08x\n", |
|
|
|
|
optdata->componentTable, |
|
|
|
|
optdata->componentTable_length)); |
|
|
|
|
optdata->componentTable, |
|
|
|
|
optdata->componentTable_length )); |
|
|
|
|
GXV_TRACE(( "ligatureTable: offset=0x%08x length=0x%08x\n", |
|
|
|
|
optdata->ligatureTable, |
|
|
|
|
optdata->ligatureTable_length)); |
|
|
|
|
optdata->ligatureTable, |
|
|
|
|
optdata->ligatureTable_length )); |
|
|
|
|
|
|
|
|
|
GXV_EXIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#define GXV_MORX_LIGACTION_ENTRY_SIZE 4 |
|
|
|
|
|
|
|
|
|
#define GXV_MORX_LIGACTION_ENTRY_SIZE 4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
gxv_morx_subtable_type2_ligActionIndex_validate( FT_Bytes table, |
|
|
|
|
FT_UShort ligActionIndex, |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
gxv_morx_subtable_type2_ligActionIndex_validate( |
|
|
|
|
FT_Bytes table, |
|
|
|
|
FT_UShort ligActionIndex, |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
{ |
|
|
|
|
/* access ligActionTable */ |
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = valid->xstatetable.optdata; |
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = |
|
|
|
|
valid->xstatetable.optdata; |
|
|
|
|
|
|
|
|
|
FT_Bytes lat_base = table + optdata->ligActionTable; |
|
|
|
|
FT_Bytes p = lat_base + ligActionIndex * GXV_MORX_LIGACTION_ENTRY_SIZE; |
|
|
|
|
FT_Bytes p = lat_base + |
|
|
|
|
ligActionIndex * GXV_MORX_LIGACTION_ENTRY_SIZE; |
|
|
|
|
FT_Bytes lat_limit = lat_base + optdata->ligActionTable; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -152,32 +174,35 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lig_action = FT_NEXT_ULONG( p ); |
|
|
|
|
last = (lig_action & 0x80000000) / 0x80000000; |
|
|
|
|
store = (lig_action & 0x40000000) / 0x40000000; |
|
|
|
|
offset = lig_action & 0x3FFFFFFF; |
|
|
|
|
|
|
|
|
|
last = (lig_action & 0x80000000UL) / 0x80000000UL; |
|
|
|
|
store = (lig_action & 0x40000000UL) / 0x40000000UL; |
|
|
|
|
offset = lig_action & 0x3FFFFFFFUL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
gxv_morx_subtable_type2_entry_validate( FT_UShort state, |
|
|
|
|
FT_UShort flags, |
|
|
|
|
GXV_StateTable_GlyphOffsetDesc |
|
|
|
|
glyphOffset, |
|
|
|
|
FT_Bytes table, |
|
|
|
|
FT_Bytes limit, |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
gxv_morx_subtable_type2_entry_validate( |
|
|
|
|
FT_UShort state, |
|
|
|
|
FT_UShort flags, |
|
|
|
|
GXV_StateTable_GlyphOffsetDesc glyphOffset, |
|
|
|
|
FT_Bytes table, |
|
|
|
|
FT_Bytes limit, |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
{ |
|
|
|
|
FT_UShort setComponent; |
|
|
|
|
FT_UShort dontAdvance; |
|
|
|
|
FT_UShort performAction; |
|
|
|
|
FT_UShort reserved; |
|
|
|
|
FT_UShort ligActionIndex; |
|
|
|
|
|
|
|
|
|
setComponent = ( flags & 0x8000 ) / 0x8000; |
|
|
|
|
dontAdvance = ( flags & 0x4000 ) / 0x4000; |
|
|
|
|
performAction = ( flags & 0x2000 ) / 0x2000; |
|
|
|
|
FT_UShort setComponent; |
|
|
|
|
FT_UShort dontAdvance; |
|
|
|
|
FT_UShort performAction; |
|
|
|
|
FT_UShort reserved; |
|
|
|
|
FT_UShort ligActionIndex; |
|
|
|
|
|
|
|
|
|
FT_UNUSED( state ); |
|
|
|
|
FT_UNUSED( limit ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setComponent = ( flags & 0x8000U ) / 0x8000U; |
|
|
|
|
dontAdvance = ( flags & 0x4000 ) / 0x4000; |
|
|
|
|
performAction = ( flags & 0x2000 ) / 0x2000; |
|
|
|
|
reserved = flags & 0x1FFF; |
|
|
|
|
ligActionIndex = glyphOffset.u; |
|
|
|
|
|
|
|
|
@ -185,7 +210,8 @@ |
|
|
|
|
GXV_TRACE(( " reserved 14bit is non-zero\n" )); |
|
|
|
|
|
|
|
|
|
if ( 0 < ligActionIndex ) |
|
|
|
|
gxv_morx_subtable_type2_ligActionIndex_validate( table, ligActionIndex, valid ); |
|
|
|
|
gxv_morx_subtable_type2_ligActionIndex_validate( |
|
|
|
|
table, ligActionIndex, valid ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -193,23 +219,29 @@ |
|
|
|
|
gxv_morx_subtable_type2_ligatureTable_validate( FT_Bytes table, |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
{ |
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = valid->xstatetable.optdata; |
|
|
|
|
GXV_morx_subtable_type2_StateOptRecData optdata = |
|
|
|
|
valid->xstatetable.optdata; |
|
|
|
|
|
|
|
|
|
FT_Bytes p = table + optdata->ligatureTable; |
|
|
|
|
FT_Bytes limit = table + optdata->ligatureTable |
|
|
|
|
+ optdata->ligatureTable_length; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GXV_NAME_ENTER( "morx chain subtable type2 - substitutionTable" ); |
|
|
|
|
|
|
|
|
|
if ( 0 != optdata->ligatureTable ) |
|
|
|
|
{ |
|
|
|
|
/* Apple does not give specification of ligatureTable format */ |
|
|
|
|
while ( p < limit ) |
|
|
|
|
{ |
|
|
|
|
FT_UShort lig_gid; |
|
|
|
|
FT_UShort lig_gid; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GXV_LIMIT_CHECK( 2 ); |
|
|
|
|
lig_gid = FT_NEXT_USHORT( p ); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GXV_EXIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -220,20 +252,30 @@ |
|
|
|
|
GXV_Validator valid ) |
|
|
|
|
{ |
|
|
|
|
FT_Bytes p = table; |
|
|
|
|
|
|
|
|
|
GXV_morx_subtable_type2_StateOptRec lig_rec; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GXV_NAME_ENTER( "morx chain subtable type2 (Ligature Substitution)" ); |
|
|
|
|
|
|
|
|
|
GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); |
|
|
|
|
|
|
|
|
|
valid->xstatetable.optdata = &lig_rec; |
|
|
|
|
valid->xstatetable.optdata_load_func = gxv_morx_subtable_type2_opttable_load; |
|
|
|
|
valid->xstatetable.subtable_setup_func = gxv_morx_subtable_type2_subtable_setup; |
|
|
|
|
valid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_USHORT; |
|
|
|
|
valid->xstatetable.entry_validate_func = gxv_morx_subtable_type2_entry_validate; |
|
|
|
|
valid->xstatetable.optdata = |
|
|
|
|
&lig_rec; |
|
|
|
|
valid->xstatetable.optdata_load_func = |
|
|
|
|
gxv_morx_subtable_type2_opttable_load; |
|
|
|
|
valid->xstatetable.subtable_setup_func = |
|
|
|
|
gxv_morx_subtable_type2_subtable_setup; |
|
|
|
|
valid->xstatetable.entry_glyphoffset_fmt = |
|
|
|
|
GXV_GLYPHOFFSET_USHORT; |
|
|
|
|
valid->xstatetable.entry_validate_func = |
|
|
|
|
gxv_morx_subtable_type2_entry_validate; |
|
|
|
|
|
|
|
|
|
gxv_XStateTable_validate( p, limit, valid ); |
|
|
|
|
|
|
|
|
|
p += valid->subtable_length; |
|
|
|
|
gxv_morx_subtable_type2_ligatureTable_validate( table, valid ); |
|
|
|
|
|
|
|
|
|
GXV_EXIT; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|