summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Arnold <darnold@adobe.com>2016-11-02 14:49:51 -0700
committerDave Arnold <darnold@adobe.com>2016-11-02 15:33:13 -0700
commit304f0383ef6a3d242d4978274e9799163013e311 (patch)
tree8057a5410b7e69d3cde135d1474bf03ac0520081
parent776a712be821d744edd82bab932325b382d3799c (diff)
downloadfreetype2-304f0383ef6a3d242d4978274e9799163013e311.tar.gz
[truetype] Fix HVAR bugs with more than one data item
* src/truetype/ttgxvar.c (ft_var_load_hvar, tt_adjust_advance): rename regionCount to regionIdxCount. Clean up some comments.
-rw-r--r--src/truetype/ttgxvar.c68
-rw-r--r--src/truetype/ttgxvar.h30
2 files changed, 51 insertions, 47 deletions
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 718f34c57..e5ed512a3 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -432,6 +432,8 @@
FT_ULong table_offset;
FT_ULong store_offset;
FT_ULong map_offset;
+ FT_ULong * dataOffsetArray = NULL;
+
FT_TRACE2(( "HVAR " ));
@@ -465,8 +467,6 @@
/* parse item variation store */
{
FT_UShort format;
- FT_ULong data_offset_array_offset;
- FT_ULong data_offset;
FT_ULong region_offset;
GX_HVStore itemStore;
FT_UInt i, j, k;
@@ -490,13 +490,20 @@
hvarTable = blend->hvar_table;
itemStore = &hvarTable->itemStore;
+ /* read top level fields */
if ( FT_READ_ULONG( region_offset ) ||
FT_READ_USHORT( itemStore->dataCount ) )
goto Exit;
- /* save position of item variation data offsets */
- /* we'll parse region list first, then come back */
- data_offset_array_offset = FT_STREAM_POS();
+ /* make temporary copy of item variation data offsets */
+ /* we'll parse region list first, then come back */
+ if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
+ goto Exit;
+ for ( i=0; i<itemStore->dataCount; i++ )
+ {
+ if ( FT_READ_ULONG( dataOffsetArray[i] ) )
+ goto Exit;
+ }
/* parse array of region records (region list) */
if ( FT_STREAM_SEEK( table_offset + store_offset + region_offset ) )
@@ -533,50 +540,47 @@
}
/* end of region list parse */
- /* parse array of item variation data subtables */
- if ( FT_STREAM_SEEK( data_offset_array_offset ) )
- goto Exit;
-
+ /* use dataOffsetArray now to parse varData items */
if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
- goto Exit;
+ goto Exit;
- hvarData = itemStore->varData;
for ( i=0; i<itemStore->dataCount; i++ )
{
- if ( FT_READ_ULONG( data_offset ) )
+ hvarData = &itemStore->varData[i];
+
+ if ( FT_STREAM_SEEK( table_offset + store_offset + dataOffsetArray[i] ) )
goto Exit;
- if ( FT_STREAM_SEEK( table_offset + store_offset + data_offset ) ||
- FT_READ_USHORT( hvarData->itemCount ) ||
+ if ( FT_READ_USHORT( hvarData->itemCount ) ||
FT_READ_USHORT( shortDeltaCount ) ||
- FT_READ_USHORT( hvarData->regionCount ) )
+ FT_READ_USHORT( hvarData->regionIdxCount ) )
goto Exit;
/* check some data consistency */
- if ( shortDeltaCount > hvarData->regionCount )
+ if ( shortDeltaCount > hvarData->regionIdxCount )
{
FT_TRACE2(( "bad short count %d or region count %d\n",
- shortDeltaCount, hvarData->regionCount ));
+ shortDeltaCount, hvarData->regionIdxCount ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
- if ( hvarData->regionCount > itemStore->regionCount )
+ if ( hvarData->regionIdxCount > itemStore->regionCount )
{
FT_TRACE2(( "inconsistent regionCount %d in varData[ %d ]\n",
- hvarData->regionCount, i ));
+ hvarData->regionIdxCount, i ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
/* parse region indices */
- if ( FT_NEW_ARRAY( hvarData->regionIndices, hvarData->regionCount ) )
+ if ( FT_NEW_ARRAY( hvarData->regionIndices, hvarData->regionIdxCount ) )
goto Exit;
- for ( j=0; j<hvarData->regionCount; j++ )
+ for ( j=0; j<hvarData->regionIdxCount; j++ )
{
if ( FT_READ_USHORT( hvarData->regionIndices[j] ) )
goto Exit;
- if ( hvarData->regionIndices[j] >= hvarData->regionCount )
+ if ( hvarData->regionIndices[j] >= itemStore->regionCount )
{
FT_TRACE2(( "bad region index %d\n", hvarData->regionIndices[j] ));
error = FT_THROW( Invalid_File_Format );
@@ -584,15 +588,15 @@
}
}
- /* parse delta set */
- /* on input, deltas are ( shortDeltaCount + regionCount ) bytes each */
- /* on output, deltas are expanded to regionCount shorts each */
- if ( FT_NEW_ARRAY( hvarData->deltaSet, hvarData->regionCount * hvarData->itemCount ) )
+ /* parse delta set */
+ /* on input, deltas are ( shortDeltaCount + regionIdxCount ) bytes each */
+ /* on output, deltas are expanded to regionIdxCount shorts each */
+ if ( FT_NEW_ARRAY( hvarData->deltaSet, hvarData->regionIdxCount * hvarData->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<hvarData->itemCount * hvarData->regionCount; )
+ for ( j=0; j<hvarData->itemCount * hvarData->regionIdxCount; )
{
for ( k=0; k<shortDeltaCount; k++,j++ )
{
@@ -602,7 +606,7 @@
goto Exit;
hvarData->deltaSet[j] = delta;
}
- for ( ; k<hvarData->regionCount; k++,j++ )
+ for ( ; k<hvarData->regionIdxCount; k++,j++ )
{
/* read the (signed) byte deltas */
FT_Char delta;
@@ -690,6 +694,7 @@
error = FT_Err_Ok;
Exit:
+ FT_FREE( dataOffsetArray );
if ( error == FT_Err_Ok )
blend->hvar_checked = TRUE;
}
@@ -742,11 +747,11 @@
outerIndex = face->blend->hvar_table->widthMap.outerIndex[ gindex ];
innerIndex = face->blend->hvar_table->widthMap.innerIndex[ gindex ];
varData = &face->blend->hvar_table->itemStore.varData[ outerIndex ];
- deltaSet = &varData->deltaSet[ face->blend->hvar_table->itemStore.regionCount * innerIndex ];
+ deltaSet = &varData->deltaSet[ varData->regionIdxCount * innerIndex ];
- /* see pseudo code from Font Variations Overview */
+ /* see pseudo code from Font Variations Overview */
/* outer loop steps through master designs to be blended */
- for ( master=0; master<varData->regionCount; master++ )
+ for ( master=0; master<varData->regionIdxCount; master++ )
{
FT_UInt regionIndex = varData->regionIndices[ master ];
GX_AxisCoords axis = face->blend->hvar_table->itemStore.varRegionList[ regionIndex ].axisList;
@@ -797,7 +802,6 @@
FT_TRACE4(( "]\n" ));
/* apply the accumulated adjustment to the default to derive the interpolated value */
- /* TODO check rounding: *aadvance is short */
*aadvance += FT_fixedToInt( netAdjustment );
Exit:
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index 956000c76..94300d962 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -74,32 +74,32 @@ FT_BEGIN_HEADER
typedef struct GX_HVarData_
{
FT_UInt itemCount; /* # delta sets per item */
- FT_UInt regionCount; /* # regions in this var data */
+ FT_UInt regionIdxCount; /* # region indices in this data */
FT_UInt* regionIndices; /* array of regionCount indices */
/* these index the varRegionList */
FT_Short* deltaSet; /* array of itemCount deltas */
- /* use innerIndex for this array */
+ /* use innerIndex for this array */
} GX_HVarDataRec, *GX_HVarData;
- typedef struct GX_AxisCoords_ /* contribution of one axis to a region */
+ typedef struct GX_AxisCoords_ /* contribution of one axis to a region */
{
FT_Fixed startCoord;
- FT_Fixed peakCoord; /* zero means no effect (factor = 1) */
+ FT_Fixed peakCoord; /* zero means no effect (factor = 1) */
FT_Fixed endCoord;
} GX_AxisCoordsRec, *GX_AxisCoords;
typedef struct GX_HVarRegion_
{
- GX_AxisCoords axisList; /* array of axisCount records */
+ GX_AxisCoords axisList; /* array of axisCount records */
} GX_HVarRegionRec, *GX_HVarRegion;
- typedef struct GX_HVStoreRec_ /* HVAR item variation store */
+ typedef struct GX_HVStoreRec_ /* HVAR item variation store */
{
FT_UInt dataCount;
- GX_HVarData varData; /* array of dataCount records */
- /* use outerIndex for this array */
+ GX_HVarData varData; /* array of dataCount records */
+ /* use outerIndex for this array */
FT_UShort axisCount;
- FT_UInt regionCount; /* total # regions defined */
+ FT_UInt regionCount; /* total # regions defined */
GX_HVarRegion varRegionList;
} GX_HVStoreRec, *GX_HVStore;
@@ -107,16 +107,16 @@ FT_BEGIN_HEADER
typedef struct GX_WidthMapRec_
{
FT_UInt mapCount;
- FT_UInt* outerIndex; /* indices to item var data */
- FT_UInt* innerIndex; /* indices to delta set */
+ FT_UInt* outerIndex; /* indices to item var data */
+ FT_UInt* innerIndex; /* indices to delta set */
} GX_WidthMapRec, *GX_WidthMap;
typedef struct GX_HVarRec_
{
- GX_HVStoreRec itemStore; /* Item Variation Store */
- GX_WidthMapRec widthMap; /* Advance Width Mapping */
- /* GX_LSBMap LsbMap; Not implemented */
- /* GX_RSBMap RsbMap; Not implemented */
+ GX_HVStoreRec itemStore; /* Item Variation Store */
+ GX_WidthMapRec widthMap; /* Advance Width Mapping */
+ /* GX_LSBMap LsbMap; Not implemented */
+ /* GX_RSBMap RsbMap; Not implemented */
} GX_HVarTableRec, *GX_HVarTable;
/*************************************************************************/