[truetype] Updates for the forthcoming OpenType 1.9 standard (1/2).

This is in preparation for implementing `DeltaSetIndexMap` format 1, which
is used by `COLR` v1 tables, and which allows 32bit indices.

  https://docs.microsoft.com/en-us/typography/opentype/otspec190/delta/otvarcommonformats_delta.html

* src/truetype/ttgxvar.h (GX_DeltaSetIdxMapRec): Change type of `mapCount`
to `FT_ULong`.

* src/truetype/ttgxvar.c (ft_var_load_delta_set_index_mapping): Add argument
for passing the table size; update caller.
Implement new format.
This commit is contained in:
Werner Lemberg 2021-11-13 14:41:40 +01:00
parent d31bafcb9c
commit 93e6b3e8e9
2 changed files with 49 additions and 19 deletions

View File

@ -664,37 +664,66 @@
ft_var_load_delta_set_index_mapping( TT_Face face,
FT_ULong offset,
GX_DeltaSetIdxMap map,
GX_ItemVarStore itemStore )
GX_ItemVarStore itemStore,
FT_ULong table_len )
{
FT_Stream stream = FT_FACE_STREAM( face );
FT_Memory memory = stream->memory;
FT_Error error;
FT_Error error;
FT_UShort format;
FT_UInt entrySize;
FT_UInt innerBitCount;
FT_UInt innerIndexMask;
FT_UInt i, j;
FT_Byte format;
FT_Byte entryFormat;
FT_UInt entrySize;
FT_UInt innerBitCount;
FT_UInt innerIndexMask;
FT_ULong i;
FT_UInt j;
if ( FT_STREAM_SEEK( offset ) ||
FT_READ_USHORT( format ) ||
FT_READ_USHORT( map->mapCount ) )
if ( FT_STREAM_SEEK( offset ) ||
FT_READ_BYTE( format ) ||
FT_READ_BYTE( entryFormat ) )
goto Exit;
if ( format & 0xFFC0 )
if ( format == 0 )
{
if ( FT_READ_USHORT( map->mapCount ) )
goto Exit;
}
else if ( format == 1 ) /* new in OpenType 1.9 */
{
if ( FT_READ_ULONG( map->mapCount ) )
goto Exit;
}
else
{
FT_TRACE2(( "bad map format %d\n", format ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
if ( entryFormat & 0xC0 )
{
FT_TRACE2(( "bad entry format %d\n", format ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
/* bytes per entry: 1, 2, 3, or 4 */
entrySize = ( ( format & 0x0030 ) >> 4 ) + 1;
innerBitCount = ( format & 0x000F ) + 1;
entrySize = ( ( entryFormat & 0x30 ) >> 4 ) + 1;
innerBitCount = ( entryFormat & 0x0F ) + 1;
innerIndexMask = ( 1 << innerBitCount ) - 1;
/* rough sanity check */
if ( map->mapCount * entrySize > table_len )
{
FT_TRACE1(( "ft_var_load_delta_set_index_mapping:"
" invalid number of delta-set index mappings\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) )
goto Exit;
@ -723,7 +752,7 @@
if ( outerIndex >= itemStore->dataCount )
{
FT_TRACE2(( "outerIndex[%d] == %d out of range\n",
FT_TRACE2(( "outerIndex[%ld] == %d out of range\n",
i,
outerIndex ));
error = FT_THROW( Invalid_Table );
@ -736,7 +765,7 @@
if ( innerIndex >= itemStore->varData[outerIndex].itemCount )
{
FT_TRACE2(( "innerIndex[%d] == %d out of range\n",
FT_TRACE2(( "innerIndex[%ld] == %d out of range\n",
i,
innerIndex ));
error = FT_THROW( Invalid_Table );
@ -861,7 +890,8 @@
face,
table_offset + widthMap_offset,
&table->widthMap,
&table->itemStore );
&table->itemStore,
table_len );
if ( error )
goto Exit;
}

View File

@ -106,9 +106,9 @@ FT_BEGIN_HEADER
typedef struct GX_DeltaSetIdxMapRec_
{
FT_UInt mapCount;
FT_UInt* outerIndex; /* indices to item var data */
FT_UInt* innerIndex; /* indices to delta set */
FT_ULong mapCount;
FT_UInt* outerIndex; /* indices to item var data */
FT_UInt* innerIndex; /* indices to delta set */
} GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;