From e4f7673e46450298db1ce5fda8a3d310cfb50d78 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sat, 13 Nov 2021 21:11:00 +0100 Subject: [PATCH] [truetype] Updates for the forthcoming OpenType 1.9 standard (2/2). * src/truetype/ttgxvar.c (ft_var_load_item_variation_store): s/shortDeltaCount/wordDeltaCount/ (as done in the specification, too). Recognize new format and reject it for now. --- src/truetype/ttgxvar.c | 65 ++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 553e27d0c..7f2db0cbd 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -457,7 +457,8 @@ FT_UShort format; FT_ULong region_offset; FT_UInt i, j, k; - FT_UInt shortDeltaCount; + FT_UInt wordDeltaCount; + FT_Bool long_words; GX_Blend blend = face->blend; GX_ItemVarData varData; @@ -572,15 +573,18 @@ goto Exit; if ( FT_READ_USHORT( varData->itemCount ) || - FT_READ_USHORT( shortDeltaCount ) || + FT_READ_USHORT( wordDeltaCount ) || FT_READ_USHORT( varData->regionIdxCount ) ) goto Exit; + long_words = !!( wordDeltaCount & 0x8000 ); + wordDeltaCount &= 0x7FFF; + /* check some data consistency */ - if ( shortDeltaCount > varData->regionIdxCount ) + if ( wordDeltaCount > varData->regionIdxCount ) { FT_TRACE2(( "bad short count %d or region count %d\n", - shortDeltaCount, + wordDeltaCount, varData->regionIdxCount )); error = FT_THROW( Invalid_Table ); goto Exit; @@ -616,39 +620,52 @@ /* Parse delta set. */ /* */ - /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes */ - /* each; on output, deltas are expanded to `regionIdxCount' shorts */ - /* each. */ + /* On input, deltas are (wordDeltaCount + regionIdxCount) bytes */ + /* each if `long_words` isn't set, and twice as much otherwise. */ + /* */ + /* On output, deltas are expanded to `regionIdxCount` shorts each. */ if ( FT_NEW_ARRAY( varData->deltaSet, varData->regionIdxCount * varData->itemCount ) ) goto Exit; - /* the delta set is stored as a 2-dimensional array of shorts; */ - /* sign-extend signed bytes to signed shorts */ - for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) + /* the delta set is stored as a 2-dimensional array of shorts */ + if ( long_words ) { - for ( k = 0; k < shortDeltaCount; k++, j++ ) + /* new in OpenType 1.9, currently for 'COLR' table only; */ + /* the deltas are interpreted as 16.16 fixed-point scaling values */ + + /* not supported yet */ + + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else + { + for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) { - /* read the short deltas */ - FT_Short delta; + for ( k = 0; k < wordDeltaCount; k++, j++ ) + { + /* read the short deltas */ + FT_Short delta; - if ( FT_READ_SHORT( delta ) ) - goto Exit; + if ( FT_READ_SHORT( delta ) ) + goto Exit; - varData->deltaSet[j] = delta; - } + varData->deltaSet[j] = delta; + } - for ( ; k < varData->regionIdxCount; k++, j++ ) - { - /* read the (signed) byte deltas */ - FT_Char delta; + for ( ; k < varData->regionIdxCount; k++, j++ ) + { + /* read the (signed) byte deltas */ + FT_Char delta; - if ( FT_READ_CHAR( delta ) ) - goto Exit; + if ( FT_READ_CHAR( delta ) ) + goto Exit; - varData->deltaSet[j] = delta; + varData->deltaSet[j] = delta; + } } } }