@ -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 ;
FT_TRACE2 ( ( " HVAR " ) ) ;
if ( FT_STREAM_SEEK ( offset ) | |
FT_READ_USHORT ( format ) )
goto Exit ;
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 ) )
goto Exit ;
for ( i = 0 ; i < itemStore - > dataCount ; i + + )
{
hvarData = & itemStore - > varData [ i ] ;
/* 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_STREAM_SEEK ( offset + dataOffsetArray [ i ] ) )
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 ) )
if ( FT_READ_USHORT ( hvarData - > itemCount ) | |
FT_READ_USHORT ( shortDeltaCount ) | |
FT_READ_USHORT ( hvarData - > regionIdxCount ) )
goto Exit ;
if ( FT_READ_USHORT ( itemStore - > axisCount ) | |
FT_READ_USHORT ( itemStore - > regionCount ) )
/* 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 ;
}
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 - > regionIdx Count ; 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 ;
}
i f ( 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 ) ;
return error ;
}
/* 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 ;
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 ;
if ( FT_READ_SHORT ( delta ) )
goto Exit ;
FT_Error error ;
hvarData - > deltaSet [ j ] = delta ;
}
GX_Blend blend = face - > blend ;
GX_WidthMap widthMap ;
for ( ; k < hvarData - > regionIdxCount ; k + + , j + + )
{
/* read the (signed) byte deltas */
FT_Char delta ;
FT_UShort format ;
FT_UInt entrySize ;
FT_UInt innerBitCount ;
FT_UInt innerIndexMask ;
FT_UInt i , j ;
if ( FT_READ_CHAR ( delta ) )
goto Exit ;
widthMap = & blend - > hvar_table - > widthMap ;
hvarData - > deltaSet [ j ] = delta ;
}
}
}
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_BYTE ( data ) )
goto Exit ;
if ( FT_READ_USHORT ( format ) | |
FT_READ_USHORT ( widthMap - > mapCount ) )
goto Exit ;
mapData = ( mapData < < 8 ) | data ;
}
if ( format & 0xFFC0 )
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 ;