ref: 9c814704c03e45b02ec88502769cdfc9af437556
parent: 7e1cce58b58a6c368ca390fa35cfc99aafa9e54d
author: Werner Lemberg <[email protected]>
date: Fri Jan 6 16:13:36 EST 2017
[truetype] Code shuffling. * src/truetype/ttgxvar.c (): Split off loading of item variation store and delta set index mapping into... (ft_var_load_item_variation_store, ft_var_load_delta_set_index_mapping): ... new functions.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2017-01-06 Werner Lemberg <[email protected]>
+ [truetype] Code shuffling.
+
+ * src/truetype/ttgxvar.c (): Split off loading of item variation
+ store and delta set index mapping into...
+ (ft_var_load_item_variation_store,
+ ft_var_load_delta_set_index_mapping): ... new functions.
+
+2017-01-06 Werner Lemberg <[email protected]>
+
[truetype] Add HVAR access without advance width map.
* src/truetype/ttgxvar.c (ft_var_load_hvar): Handle case where
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -404,352 +404,386 @@
( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
- /*************************************************************************/
- /* */
- /* <Function> */
- /* ft_var_load_hvar */
- /* */
- /* <Description> */
- /* Parse the `HVAR' table and set `blend->hvar_loaded' to TRUE. */
- /* */
- /* On success, `blend->hvar_checked' is set to TRUE. */
- /* */
- /* Some memory may remain allocated on error; it is always freed in */
- /* `tt_done_blend', however. */
- /* */
- /* <InOut> */
- /* face :: The font face. */
- /* */
- /* <Return> */
- /* FreeType error code. 0 means success. */
- /* */
static FT_Error
- ft_var_load_hvar( TT_Face face )
+ ft_var_load_item_variation_store( TT_Face face,
+ FT_ULong offset )
{
FT_Stream stream = FT_FACE_STREAM( face );
FT_Memory memory = stream->memory;
- GX_Blend blend = face->blend;
-
FT_Error error;
- FT_UShort majorVersion;
- FT_ULong table_len;
- FT_ULong table_offset;
- FT_ULong store_offset;
- FT_ULong widthMap_offset;
+ FT_UShort format;
+ FT_ULong region_offset;
+ FT_UInt i, j, k;
+ FT_UInt shortDeltaCount;
+ GX_Blend blend = face->blend;
+ GX_HVStore itemStore;
+ GX_HVarTable hvarTable;
+ GX_HVarData hvarData;
+
FT_ULong* dataOffsetArray = NULL;
- blend->hvar_loaded = TRUE;
+ if ( FT_STREAM_SEEK( offset ) ||
+ FT_READ_USHORT( format ) )
+ goto Exit;
- FT_TRACE2(( "HVAR " ));
-
- error = face->goto_table( face, TTAG_HVAR, stream, &table_len );
- if ( error )
+ if ( format != 1 )
{
- FT_TRACE2(( "is missing\n" ));
+ FT_TRACE2(( "bad store format %d\n", format ));
+ error = FT_THROW( Invalid_Table );
goto Exit;
}
- table_offset = FT_STREAM_POS();
+ if ( FT_NEW( blend->hvar_table ) ) /* allocate table at top level */
+ goto Exit;
- /* skip minor version */
- if ( FT_READ_USHORT( majorVersion ) ||
- FT_STREAM_SKIP( 2 ) )
+ hvarTable = blend->hvar_table;
+ itemStore = &hvarTable->itemStore;
+
+ /* read top level fields */
+ if ( FT_READ_ULONG( region_offset ) ||
+ FT_READ_USHORT( itemStore->dataCount ) )
goto Exit;
- if ( majorVersion != 1 )
+
+ /* make temporary copy of item variation data offsets; */
+ /* we will parse region list first, then come back */
+ if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
+ goto Exit;
+
+ for ( i = 0; i < itemStore->dataCount; i++ )
{
- FT_TRACE2(( "bad table version %d\n", majorVersion ));
+ if ( FT_READ_ULONG( dataOffsetArray[i] ) )
+ goto Exit;
+ }
+
+ /* parse array of region records (region list) */
+ if ( FT_STREAM_SEEK( offset + region_offset ) )
+ goto Exit;
+
+ if ( FT_READ_USHORT( itemStore->axisCount ) ||
+ FT_READ_USHORT( itemStore->regionCount ) )
+ goto Exit;
+
+ if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
+ {
+ FT_TRACE2(( "ft_var_load_item_variation_store:"
+ " number of axes in `hvar' and `fvar'\n"
+ " "
+ " table are different\n" ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
- if ( FT_READ_ULONG( store_offset ) ||
- FT_READ_ULONG( widthMap_offset ) )
+ if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) )
goto Exit;
- /* parse item variation store */
+ for ( i = 0; i < itemStore->regionCount; i++ )
{
- FT_UShort format;
- FT_ULong region_offset;
- FT_UInt i, j, k;
- FT_UInt shortDeltaCount;
+ GX_AxisCoords axisCoords;
- GX_HVStore itemStore;
- GX_HVarTable hvarTable;
- GX_HVarData hvarData;
-
- if ( FT_STREAM_SEEK( table_offset + store_offset ) ||
- FT_READ_USHORT( format ) )
+ if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList,
+ itemStore->axisCount ) )
goto Exit;
- if ( format != 1 )
+
+ axisCoords = itemStore->varRegionList[i].axisList;
+
+ for ( j = 0; j < itemStore->axisCount; j++ )
{
- FT_TRACE2(( "bad store format %d\n", format ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
+ FT_Short start, peak, end;
+
+
+ if ( FT_READ_SHORT( start ) ||
+ FT_READ_SHORT( peak ) ||
+ FT_READ_SHORT( end ) )
+ goto Exit;
+
+ axisCoords[j].startCoord = FT_fdot14ToFixed( start );
+ axisCoords[j].peakCoord = FT_fdot14ToFixed( peak );
+ axisCoords[j].endCoord = FT_fdot14ToFixed( end );
}
+ }
- if ( FT_NEW( blend->hvar_table ) ) /* allocate table at top level */
- goto Exit;
+ /* end of region list parse */
- hvarTable = blend->hvar_table;
- itemStore = &hvarTable->itemStore;
+ /* use dataOffsetArray now to parse varData items */
+ if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
+ goto Exit;
- /* read top level fields */
- if ( FT_READ_ULONG( region_offset ) ||
- FT_READ_USHORT( itemStore->dataCount ) )
+ for ( i = 0; i < itemStore->dataCount; i++ )
+ {
+ hvarData = &itemStore->varData[i];
+
+ if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
goto Exit;
- /* make temporary copy of item variation data offsets; */
- /* we will parse region list first, then come back */
- if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
+ if ( FT_READ_USHORT( hvarData->itemCount ) ||
+ FT_READ_USHORT( shortDeltaCount ) ||
+ FT_READ_USHORT( hvarData->regionIdxCount ) )
goto Exit;
- for ( i = 0; i < itemStore->dataCount; i++ )
+ /* check some data consistency */
+ if ( shortDeltaCount > hvarData->regionIdxCount )
{
- if ( FT_READ_ULONG( dataOffsetArray[i] ) )
- goto Exit;
+ FT_TRACE2(( "bad short count %d or region count %d\n",
+ shortDeltaCount,
+ hvarData->regionIdxCount ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
}
- /* parse array of region records (region list) */
- if ( FT_STREAM_SEEK( table_offset + store_offset + region_offset ) )
- goto Exit;
-
- if ( FT_READ_USHORT( itemStore->axisCount ) ||
- FT_READ_USHORT( itemStore->regionCount ) )
- goto Exit;
-
- if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
+ if ( hvarData->regionIdxCount > itemStore->regionCount )
{
- FT_TRACE2(( "ft_var_load_hvar: number of axes in `hvar' and `fvar'\n"
- " table are different\n" ));
+ FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n",
+ hvarData->regionIdxCount,
+ i ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
- if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) )
+ /* parse region indices */
+ if ( FT_NEW_ARRAY( hvarData->regionIndices,
+ hvarData->regionIdxCount ) )
goto Exit;
- for ( i = 0; i < itemStore->regionCount; i++ )
+ for ( j = 0; j < hvarData->regionIdxCount; j++ )
{
- GX_AxisCoords axisCoords;
-
-
- if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList,
- itemStore->axisCount ) )
+ if ( FT_READ_USHORT( hvarData->regionIndices[j] ) )
goto Exit;
- axisCoords = itemStore->varRegionList[i].axisList;
-
- for ( j = 0; j < itemStore->axisCount; j++ )
+ if ( hvarData->regionIndices[j] >= itemStore->regionCount )
{
- FT_Short start, peak, end;
-
-
- if ( FT_READ_SHORT( start ) ||
- FT_READ_SHORT( peak ) ||
- FT_READ_SHORT( end ) )
- goto Exit;
-
- axisCoords[j].startCoord = FT_fdot14ToFixed( start );
- axisCoords[j].peakCoord = FT_fdot14ToFixed( peak );
- axisCoords[j].endCoord = FT_fdot14ToFixed( end );
+ FT_TRACE2(( "bad region index %d\n",
+ hvarData->regionIndices[j] ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
}
}
- /* end of region list parse */
-
- /* use dataOffsetArray now to parse varData items */
- if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
+ /* 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;
- for ( i = 0; i < itemStore->dataCount; i++ )
+ /* 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->regionIdxCount; )
{
- hvarData = &itemStore->varData[i];
+ for ( k = 0; k < shortDeltaCount; k++, j++ )
+ {
+ /* read the short deltas */
+ FT_Short delta;
- if ( FT_STREAM_SEEK( table_offset +
- store_offset +
- dataOffsetArray[i] ) )
- goto Exit;
- if ( FT_READ_USHORT( hvarData->itemCount ) ||
- FT_READ_USHORT( shortDeltaCount ) ||
- FT_READ_USHORT( hvarData->regionIdxCount ) )
- goto Exit;
+ if ( FT_READ_SHORT( delta ) )
+ goto Exit;
- /* check some data consistency */
- if ( shortDeltaCount > hvarData->regionIdxCount )
- {
- FT_TRACE2(( "bad short count %d or region count %d\n",
- shortDeltaCount,
- hvarData->regionIdxCount ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
+ hvarData->deltaSet[j] = delta;
}
- if ( hvarData->regionIdxCount > itemStore->regionCount )
+ for ( ; k < hvarData->regionIdxCount; k++, j++ )
{
- FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n",
- hvarData->regionIdxCount,
- i ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
+ /* read the (signed) byte deltas */
+ FT_Char delta;
- /* parse region indices */
- if ( FT_NEW_ARRAY( hvarData->regionIndices,
- hvarData->regionIdxCount ) )
- goto Exit;
- for ( j = 0; j < hvarData->regionIdxCount; j++ )
- {
- if ( FT_READ_USHORT( hvarData->regionIndices[j] ) )
+ if ( FT_READ_CHAR( delta ) )
goto Exit;
- if ( hvarData->regionIndices[j] >= itemStore->regionCount )
- {
- FT_TRACE2(( "bad region index %d\n",
- hvarData->regionIndices[j] ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
+ hvarData->deltaSet[j] = delta;
}
+ }
+ }
- /* 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;
+ Exit:
+ FT_FREE( dataOffsetArray );
- /* 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->regionIdxCount; )
- {
- for ( k = 0; k < shortDeltaCount; k++, j++ )
- {
- /* read the short deltas */
- FT_Short delta;
+ return error;
+ }
- if ( FT_READ_SHORT( delta ) )
- goto Exit;
+ static FT_Error
+ ft_var_load_delta_set_index_mapping( TT_Face face,
+ FT_ULong offset )
+ {
+ FT_Stream stream = FT_FACE_STREAM( face );
+ FT_Memory memory = stream->memory;
- hvarData->deltaSet[j] = delta;
- }
+ FT_Error error;
- for ( ; k < hvarData->regionIdxCount; k++, j++ )
- {
- /* read the (signed) byte deltas */
- FT_Char delta;
+ GX_Blend blend = face->blend;
+ GX_WidthMap widthMap;
+ FT_UShort format;
+ FT_UInt entrySize;
+ FT_UInt innerBitCount;
+ FT_UInt innerIndexMask;
+ FT_UInt i, j;
- if ( FT_READ_CHAR( delta ) )
- goto Exit;
- hvarData->deltaSet[j] = delta;
- }
- }
- }
+ widthMap = &blend->hvar_table->widthMap;
+
+ if ( FT_STREAM_SEEK( offset ) ||
+ FT_READ_USHORT( format ) ||
+ FT_READ_USHORT( widthMap->mapCount ) )
+ goto Exit;
+
+ if ( format & 0xFFC0 )
+ {
+ FT_TRACE2(( "bad map format %d\n", format ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
}
- /* end parse item variation store */
+ /* bytes per entry: 1, 2, 3, or 4 */
+ entrySize = ( ( format & 0x0030 ) >> 4 ) + 1;
+ innerBitCount = ( format & 0x000F ) + 1;
+ innerIndexMask = ( 1 << innerBitCount ) - 1;
- /* parse width map */
- if ( widthMap_offset )
+ if ( FT_NEW_ARRAY( widthMap->innerIndex, widthMap->mapCount ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY( widthMap->outerIndex, widthMap->mapCount ) )
+ goto Exit;
+
+ for ( i = 0; i < widthMap->mapCount; i++ )
{
- GX_WidthMap widthMap;
+ FT_UInt mapData = 0;
+ FT_UInt outerIndex, innerIndex;
- FT_UShort format;
- FT_UInt entrySize;
- FT_UInt innerBitCount;
- FT_UInt innerIndexMask;
- FT_UInt i, j;
+ /* read map data one unsigned byte at a time, big endian */
+ for ( j = 0; j < entrySize; j++ )
+ {
+ FT_Byte data;
- widthMap = &blend->hvar_table->widthMap;
- if ( FT_READ_USHORT( format ) ||
- FT_READ_USHORT( widthMap->mapCount ) )
- goto Exit;
+ if ( FT_READ_BYTE( data ) )
+ goto Exit;
- if ( format & 0xFFC0 )
+ mapData = ( mapData << 8 ) | data;
+ }
+
+ outerIndex = mapData >> innerBitCount;
+
+ if ( outerIndex >= blend->hvar_table->itemStore.dataCount )
{
- FT_TRACE2(( "bad map format %d\n", format ));
+ FT_TRACE2(( "outerIndex[%d] == %d out of range\n",
+ i,
+ outerIndex ));
error = FT_THROW( Invalid_Table );
goto Exit;
}
- /* bytes per entry: 1, 2, 3, or 4 */
- entrySize = ( ( format & 0x0030 ) >> 4 ) + 1;
- innerBitCount = ( format & 0x000F ) + 1;
- innerIndexMask = ( 1 << innerBitCount ) - 1;
+ widthMap->outerIndex[i] = outerIndex;
- if ( FT_NEW_ARRAY( widthMap->innerIndex, widthMap->mapCount ) )
- goto Exit;
+ innerIndex = mapData & innerIndexMask;
- if ( FT_NEW_ARRAY( widthMap->outerIndex, widthMap->mapCount ) )
- goto Exit;
-
- for ( i = 0; i < widthMap->mapCount; i++ )
+ if ( innerIndex >=
+ blend->hvar_table->itemStore.varData[outerIndex].itemCount )
{
- FT_UInt mapData = 0;
- FT_UInt outerIndex, innerIndex;
+ FT_TRACE2(( "innerIndex[%d] == %d out of range\n",
+ i,
+ innerIndex ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ widthMap->innerIndex[i] = innerIndex;
+ }
- /* read map data one unsigned byte at a time, big endian */
- for ( j = 0; j < entrySize; j++ )
- {
- FT_Byte data;
+ Exit:
+ return error;
+ }
- if ( FT_READ_BYTE( data ) )
- goto Exit;
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* ft_var_load_hvar */
+ /* */
+ /* <Description> */
+ /* Parse the `HVAR' table and set `blend->hvar_loaded' to TRUE. */
+ /* */
+ /* On success, `blend->hvar_checked' is set to TRUE. */
+ /* */
+ /* Some memory may remain allocated on error; it is always freed in */
+ /* `tt_done_blend', however. */
+ /* */
+ /* <InOut> */
+ /* face :: The font face. */
+ /* */
+ /* <Return> */
+ /* FreeType error code. 0 means success. */
+ /* */
+ static FT_Error
+ ft_var_load_hvar( TT_Face face )
+ {
+ FT_Stream stream = FT_FACE_STREAM( face );
- mapData = ( mapData << 8 ) | data;
- }
+ GX_Blend blend = face->blend;
- outerIndex = mapData >> innerBitCount;
+ FT_Error error;
+ FT_UShort majorVersion;
+ FT_ULong table_len;
+ FT_ULong table_offset;
+ FT_ULong store_offset;
+ FT_ULong widthMap_offset;
- if ( outerIndex >= blend->hvar_table->itemStore.dataCount )
- {
- FT_TRACE2(( "outerIndex[%d] == %d out of range\n",
- i,
- outerIndex ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
- widthMap->outerIndex[i] = outerIndex;
+ blend->hvar_loaded = TRUE;
- innerIndex = mapData & innerIndexMask;
+ FT_TRACE2(( "HVAR " ));
- if ( innerIndex >=
- blend->hvar_table->itemStore.varData[outerIndex].itemCount )
- {
- FT_TRACE2(( "innerIndex[%d] == %d out of range\n",
- i,
- innerIndex ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
+ error = face->goto_table( face, TTAG_HVAR, stream, &table_len );
+ if ( error )
+ {
+ FT_TRACE2(( "is missing\n" ));
+ goto Exit;
+ }
- widthMap->innerIndex[i] = innerIndex;
- }
+ table_offset = FT_STREAM_POS();
+
+ /* skip minor version */
+ if ( FT_READ_USHORT( majorVersion ) ||
+ FT_STREAM_SKIP( 2 ) )
+ goto Exit;
+ if ( majorVersion != 1 )
+ {
+ FT_TRACE2(( "bad table version %d\n", majorVersion ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
}
- /* end parse width map */
+ if ( FT_READ_ULONG( store_offset ) ||
+ FT_READ_ULONG( widthMap_offset ) )
+ goto Exit;
+ error = ft_var_load_item_variation_store(
+ face,
+ table_offset + store_offset );
+ if ( error )
+ goto Exit;
+
+ if ( widthMap_offset )
+ {
+ error = ft_var_load_delta_set_index_mapping(
+ face,
+ table_offset + widthMap_offset );
+ if ( error )
+ goto Exit;
+ }
+
FT_TRACE2(( "loaded\n" ));
error = FT_Err_Ok;
Exit:
- FT_FREE( dataOffsetArray );
-
if ( !error )
{
blend->hvar_checked = TRUE;