freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] OpenType-1.8 d5c247e 1/6: [cff] Add support for vsindex, DI


From: Dave Arnold
Subject: [freetype2] OpenType-1.8 d5c247e 1/6: [cff] Add support for vsindex, DICT & CharString
Date: Thu, 17 Nov 2016 16:23:03 +0000 (UTC)

branch: OpenType-1.8
commit d5c247e923493c1bd512961964cf6479d4ac8a0f
Author: Dave Arnold <address@hidden>
Commit: Dave Arnold <address@hidden>

    [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.
---
 src/cff/cf2font.c  |    5 +++--
 src/cff/cf2intrp.c |   21 ++++++++++++++++++---
 src/cff/cffload.c  |   27 ++++++++++++++++++---------
 src/cff/cffparse.c |   45 +++++++++++++++++++++++++++++++++++++++++----
 src/cff/cfftoken.h |    2 +-
 src/cff/cfftypes.h |    8 +++++++-
 6 files changed, 88 insertions(+), 20 deletions(-)

diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
index 6c3da5c..22044c6 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 978bcf4..6b99cd7 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 44e71f1..fd0162f 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 d4a5d4b..8f54cb0 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 a1b8ae6..f1cf336 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 912ee56..61b7e16 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           */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]