summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Arnold <darnold@adobe.com>2016-11-10 13:18:38 -0800
committerDave Arnold <darnold@adobe.com>2016-11-10 13:18:38 -0800
commitd5c247e923493c1bd512961964cf6479d4ac8a0f (patch)
treeff330ce6880e23d9cc2046d816dc8c7d2420a758
parent304f0383ef6a3d242d4978274e9799163013e311 (diff)
downloadfreetype2-d5c247e923493c1bd512961964cf6479d4ac8a0f.tar.gz
[cff] Add support for vsindex, DICT & CharString
Add cf2_cmdVSINDEX charstring operator. Add cff_parse_vsindex as a callback function. Add vsindex state machine to check for vsindex after blend. Fix stack bugs in cff_blend_doBlend. Report errors from cff_blend_build_vector. Minor comment and TRACE edits.
-rw-r--r--src/cff/cf2font.c5
-rw-r--r--src/cff/cf2intrp.c21
-rw-r--r--src/cff/cffload.c27
-rw-r--r--src/cff/cffparse.c45
-rw-r--r--src/cff/cfftoken.h2
-rw-r--r--src/cff/cfftypes.h8
6 files changed, 88 insertions, 20 deletions
diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
index 6c3da5cfa..22044c691 100644
--- a/src/cff/cf2font.c
+++ b/src/cff/cf2font.c
@@ -415,8 +415,9 @@
needExtraSetup = TRUE;
}
/* store vector inputs for blends in charstring */
- font->blend.font = subFont->blend.font; /* copy from subfont */
- font->vsindex = subFont->private_dict.vsindex; /* initial value for charstring */
+ font->blend.font = subFont->blend.font; /* copy from subfont */
+ font->blend.usedBV = FALSE; /* clear state of charstring blend */
+ font->vsindex = subFont->private_dict.vsindex; /* initial value for charstring */
font->lenNDV = lenNormalizedV;
font->NDV = normalizedV;
}
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 978bcf4bd..6b99cd73c 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -215,7 +215,7 @@
cf2_cmdESC, /* 12 */
cf2_cmdRESERVED_13, /* 13 */
cf2_cmdENDCHAR, /* 14 */
- cf2_cmdRESERVED_15, /* 15 */
+ cf2_cmdVSINDEX, /* 15 */
cf2_cmdBLEND, /* 16 */
cf2_cmdRESERVED_17, /* 17 */
cf2_cmdHSTEMHM, /* 18 */
@@ -612,12 +612,25 @@
case cf2_cmdRESERVED_2:
case cf2_cmdRESERVED_9:
case cf2_cmdRESERVED_13:
- case cf2_cmdRESERVED_15:
case cf2_cmdRESERVED_17:
/* we may get here if we have a prior error */
FT_TRACE4(( " unknown op (%d)\n", op1 ));
break;
+ case cf2_cmdVSINDEX:
+ {
+ if ( font->blend.usedBV )
+ {
+ /* vsindex not allowed after blend */
+ lastError = FT_THROW( Invalid_Glyph_Format );
+ goto exit;
+ }
+
+ font->vsindex = (FT_UInt)cf2_stack_popInt( opStack );
+ FT_TRACE4(( " %d\n", font->vsindex ));
+ break;
+ }
+
case cf2_cmdBLEND:
{
FT_UInt numBlends;
@@ -630,7 +643,9 @@
/* check cached blend vector */
if ( cff_blend_check_vector( &font->blend, font->vsindex, font->lenNDV, font->NDV ) )
{
- cff_blend_build_vector( &font->blend, font->vsindex, font->lenNDV, font->NDV );
+ lastError = cff_blend_build_vector( &font->blend, font->vsindex, font->lenNDV, font->NDV );
+ if ( lastError != FT_Err_Ok )
+ goto exit;
}
/* do the blend */
numBlends = (FT_UInt)cf2_stack_popInt( opStack );
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 44e71f1d1..fd0162f25 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1258,7 +1258,16 @@
FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */
FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
+ /* compute expected number of operands for this blend */
FT_UInt numOperands = (FT_UInt)(numBlends * blend->lenBV);
+ FT_UInt count = parser->top - 1 - parser->stack;
+
+ if ( numOperands > count )
+ {
+ FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d args\n", count ));
+ error = FT_THROW( Stack_Underflow );
+ goto Exit;
+ }
/* check if we have room for numBlends values at blend_top */
size = 5 * numBlends; /* add 5 bytes per entry */
@@ -1273,8 +1282,8 @@
}
subFont->blend_used += size;
- base = ( parser->top - 1 - parser->stack ) - numOperands;
- delta = base + numBlends;
+ base = count - numOperands; /* index of first blend arg */
+ delta = base + numBlends; /* index of first delta arg */
for ( i = 0; i < numBlends; i++ )
{
const FT_Int32 * weight = &blend->BV[1];
@@ -1323,23 +1332,21 @@ Exit:
FT_UNUSED( vsindex );
FT_ASSERT( lenNDV == 0 || NDV );
- FT_TRACE4(( "cff_blend_build_vector\n" ));
blend->builtBV = FALSE;
- /* vs = cf2_getVStore( font->decoder ); */
vs = &blend->font->vstore;
/* VStore and fvar must be consistent */
if ( lenNDV != 0 && lenNDV != vs->axisCount )
{
- FT_TRACE4(( "cff_blend_build_vector: Axis count mismatch\n" ));
+ FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
if ( vsindex >= vs->dataCount )
{
- FT_TRACE4(( "cff_blend_build_vector: vsindex out of range\n" ));
+ FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1364,7 +1371,7 @@ Exit:
if ( master == 0 )
{
blend->BV[master] = FT_FIXED_ONE;
- FT_TRACE4(( "blend vector len %d\n [ %f ", len, (double)(blend->BV[master] / 65536. ) ));
+ FT_TRACE4(( " build blend vector len %d\n [ %f ", len, (double)(blend->BV[master] / 65536. ) ));
continue;
}
@@ -1374,7 +1381,7 @@ Exit:
if ( idx >= vs->regionCount )
{
- FT_TRACE4(( "cf2_buildBlendVector: region index out of range\n" ));
+ FT_TRACE4(( " cf2_buildBlendVector: region index out of range\n" ));
error = FT_THROW( Invalid_File_Format );
goto Exit;
}
@@ -1739,6 +1746,7 @@ Exit:
/* store handle needed to access memory, vstore for blend */
subfont->blend.font = font;
+ subfont->blend.usedBV = FALSE; /* clear state */
/* set defaults */
FT_MEM_ZERO( priv, sizeof ( *priv ) );
@@ -1869,7 +1877,8 @@ Exit:
/* CFF2 does not have a private dictionary in the Top DICT */
/* but may have one in a Font DICT. We need to parse */
/* the latter here in order to load any local subrs. */
- if ( cff_load_private_dict( font, subfont, 0, 0 ) )
+ error = cff_load_private_dict( font, subfont, 0, 0 );
+ if ( error )
goto Exit;
/* read the local subrs, if any */
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index d4a5d4b75..8f54cb0e6 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -384,7 +384,6 @@
result = -result;
return result;
-
Overflow:
result = 0x7FFFFFFFL;
FT_TRACE4(( "!!!OVERFLOW:!!!" ));
@@ -796,7 +795,38 @@
return error;
}
- /* TODO: replace this test code with doBlend */
+ static FT_Error
+ cff_parse_vsindex( CFF_Parser parser )
+ {
+ /* vsindex operator can only be used in a Private DICT */
+ CFF_Private priv = (CFF_Private)parser->object;
+ FT_Byte** data = parser->stack;
+ CFF_Blend blend;
+ FT_Error error;
+
+
+ if ( !priv || !priv->subfont )
+ {
+ error = FT_ERR( Invalid_File_Format );
+ goto Exit;
+ }
+ blend = &priv->subfont->blend;
+
+ if ( blend->usedBV )
+ {
+ FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
+ error = FT_THROW( Syntax_Error );
+ goto Exit;
+ }
+ priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );
+
+ FT_TRACE4(( " %d\n", priv->vsindex ));
+ error = FT_Err_Ok;
+
+ Exit:
+ return error;
+ }
+
static FT_Error
cff_parse_blend( CFF_Parser parser )
{
@@ -808,7 +838,6 @@
FT_Error error;
error = FT_ERR( Stack_Underflow );
- FT_TRACE1(( " cff_parse_blend\n" ));
if ( !priv || !priv->subfont )
{
@@ -819,11 +848,19 @@
blend = &subFont->blend;
if ( cff_blend_check_vector( blend, priv->vsindex, subFont->lenNDV, subFont->NDV ) )
- cff_blend_build_vector( blend, priv->vsindex, subFont->lenNDV, subFont->NDV );
+ {
+ error = cff_blend_build_vector( blend, priv->vsindex, subFont->lenNDV, subFont->NDV );
+ if ( error != FT_Err_Ok )
+ goto Exit;
+ }
numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
+ FT_TRACE4(( " %d values blended\n", numBlends ));
+
error = cff_blend_doBlend(subFont, parser, numBlends );
+
+ blend->usedBV = TRUE;
Exit:
return error;
}
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index a1b8ae664..f1cf3364a 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -143,7 +143,7 @@
CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" )
CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" )
CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" )
- CFF_FIELD_NUM ( 22, vsindex, "vsindex" )
+ CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" )
CFF_FIELD_BLEND ( 23, "blend" )
CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" )
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 912ee5698..61b7e169d 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -139,7 +139,13 @@ FT_BEGIN_HEADER
typedef struct CFF_BlendRec_
{
- /* object to manage one cached blend vector */
+ /* This object manages one cached blend vector. */
+ /* There is a BlendRec for Private DICT parsing in each subfont */
+ /* and a BlendRec for charstrings in CF2_Font instance data. */
+ /* A cached BV may be used across DICTs or Charstrings if inputs */
+ /* have not changed. */
+ /* usedBV is reset at the start of each parse or charstring. */
+ /* vsindex cannot be changed after a BV is used. */
/* Note: NDV is long 32/64 bit, while BV is 16.16 (FT_Int32) */
FT_Bool builtBV; /* blendV has been built */
FT_Bool usedBV; /* blendV has been used */