diff --git a/ChangeLog b/ChangeLog index a3e33e0b2..ccdd2e5bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2017-01-06 Werner Lemberg + + [truetype] Add HVAR access without advance width map. + + * src/truetype/ttgxvar.c (ft_var_load_hvar): Handle case where + `offsetToAdvanceWidthMapping' is zero. + (tt_hadvance_adjust): Implement direct deltaSet access by glyph + index. + 2017-01-06 Werner Lemberg [pcf] Revise driver. diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index c7f389ae6..9891037d8 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -436,6 +436,7 @@ FT_ULong table_len; FT_ULong table_offset; FT_ULong store_offset; + FT_ULong widthMap_offset; FT_ULong* dataOffsetArray = NULL; @@ -464,9 +465,8 @@ goto Exit; } - /* skip map offset */ - if ( FT_READ_ULONG( store_offset ) || - FT_STREAM_SKIP( 4 ) ) + if ( FT_READ_ULONG( store_offset ) || + FT_READ_ULONG( widthMap_offset ) ) goto Exit; /* parse item variation store */ @@ -619,7 +619,7 @@ /* Parse delta set. */ /* */ - /* On input, deltas are ( shortDeltaCount + regionIdxCount ) bytes */ + /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes */ /* each; on output, deltas are expanded to `regionIdxCount' shorts */ /* each. */ if ( FT_NEW_ARRAY( hvarData->deltaSet, @@ -660,6 +660,7 @@ /* end parse item variation store */ /* parse width map */ + if ( widthMap_offset ) { GX_WidthMap widthMap; @@ -789,7 +790,6 @@ GX_HVarData varData; - FT_UInt innerIndex, outerIndex; FT_UInt master, j; FT_Fixed netAdjustment = 0; /* accumulated adjustment */ FT_Fixed scaledDelta; @@ -815,18 +815,40 @@ /* advance width adjustments are always present in an `HVAR' table, */ /* so need to test for this capability */ - if ( gindex >= face->blend->hvar_table->widthMap.mapCount ) + if ( face->blend->hvar_table->widthMap.innerIndex ) { - FT_TRACE2(( "gindex %d out of range\n", gindex )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } + FT_UInt innerIndex, outerIndex; - /* trust that HVAR parser has checked indices */ - 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[varData->regionIdxCount * innerIndex]; + + if ( gindex >= face->blend->hvar_table->widthMap.mapCount ) + { + FT_TRACE2(( "gindex %d out of range\n", gindex )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + /* trust that HVAR parser has checked indices */ + 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[varData->regionIdxCount * innerIndex]; + } + else + { + /* no widthMap data; use glyph index as inner index instead */ + /* (and value 0 for outer index) */ + + varData = &face->blend->hvar_table->itemStore.varData[0]; + + if ( gindex >= varData->itemCount ) + { + FT_TRACE2(( "gindex %d out of range\n", gindex )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + deltaSet = &varData->deltaSet[varData->regionIdxCount * gindex]; + } /* See pseudo code from `Font Variations Overview' */ /* in the OpenType specification. */ diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h index 46a77bdd8..26ba0d70f 100644 --- a/src/truetype/ttgxvar.h +++ b/src/truetype/ttgxvar.h @@ -125,8 +125,8 @@ FT_BEGIN_HEADER GX_HVStoreRec itemStore; /* Item Variation Store */ GX_WidthMapRec widthMap; /* Advance Width Mapping */ #if 0 - GX_LSBMap LsbMap; /* not implemented */ - GX_RSBMap RsbMap; /* not implemented */ + GX_LSBMap lsbMap; /* not implemented */ + GX_RSBMap rsbMap; /* not implemented */ #endif } GX_HVarTableRec, *GX_HVarTable;