freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] OpenType-1.8 c156b73 2/6: Add code to ignore operators remov


From: Dave Arnold
Subject: [freetype2] OpenType-1.8 c156b73 2/6: Add code to ignore operators removed from CFF2 spec
Date: Thu, 17 Nov 2016 16:23:03 +0000 (UTC)

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

    Add code to ignore operators removed from CFF2 spec
    
    Ignored operators clear the stack.
    Ignore return and endChar in CFF2.
    Ignore vsindex and blend in CFF.
    
    Add a nested switch for op2.
    First op2 switch handles 4 flex operators for CFF & CFF2 and all reserved
    operators common to both.
    Second op2 switch handles CFF operators that were removed from CFF2.
---
 src/cff/cf2intrp.c |  658 +++++++++++++++++++++++++++-------------------------
 1 file changed, 346 insertions(+), 312 deletions(-)

diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 6b99cd7..2dd13c6 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -273,7 +273,8 @@
     cf2_escHFLEX,        /* 34 */
     cf2_escFLEX,         /* 35 */
     cf2_escHFLEX1,       /* 36 */
-    cf2_escFLEX1         /* 37 */
+    cf2_escFLEX1,        /* 37 */
+    cf2_escRESERVED_38   /* 38      & all higher    */
   };
 
 
@@ -587,14 +588,25 @@
       {
         /* If we've reached the end of the charstring, simulate a */
         /* cf2_cmdRETURN or cf2_cmdENDCHAR.                       */
+        /* We do this for both CFF and CFF2.                      */
         if ( charstringIndex )
           op1 = cf2_cmdRETURN;  /* end of buffer for subroutine */
         else
           op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */
       }
       else
+      {
         op1 = (FT_Byte)cf2_buf_readByte( charstring );
 
+        /* explicit RETURN and ENDCHAR in CFF2 should be ignored */
+        /* Note: Trace message will report 0 instead of 11 or 14 */
+        if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) &&
+             font->isCFF2 )
+        {
+          op1 = cf2_cmdRESERVED_0;
+        }
+      }
+
       /* check for errors once per loop */
       if ( *error )
         goto exit;
@@ -619,6 +631,11 @@
 
       case cf2_cmdVSINDEX:
         {
+          FT_TRACE4(( " %d\n" ));
+
+          if ( !font->isCFF2 )
+            break;    /* clear stack & ignore */
+
           if ( font->blend.usedBV )
           {
             /* vsindex not allowed after blend */
@@ -627,7 +644,6 @@
           }
 
           font->vsindex = (FT_UInt)cf2_stack_popInt( opStack );
-          FT_TRACE4(( " %d\n", font->vsindex ));
           break;
         }
 
@@ -893,441 +909,456 @@
           FT_Byte  op2 = (FT_Byte)cf2_buf_readByte( charstring );
 
 
+          /* first switch for 2-byte operators handles CFF2      */
+          /* and opcodes that are reserved for both CFF and CFF2 */
           switch ( op2 )
           {
-          case cf2_escDOTSECTION:
-            /* something about `flip type of locking' -- ignore it */
-            FT_TRACE4(( " dotsection\n" ));
+          case cf2_escHFLEX:
+            {
+              static const FT_Bool  readFromStack[12] =
+              {
+                TRUE /* dx1 */, FALSE /* dy1 */,
+                TRUE /* dx2 */, TRUE  /* dy2 */,
+                TRUE /* dx3 */, FALSE /* dy3 */,
+                TRUE /* dx4 */, FALSE /* dy4 */,
+                TRUE /* dx5 */, FALSE /* dy5 */,
+                TRUE /* dx6 */, FALSE /* dy6 */
+              };
 
-            break;
 
-          case cf2_escAND:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
+              FT_TRACE4(( " hflex\n" ));
+
+              cf2_doFlex( opStack,
+                          &curX,
+                          &curY,
+                          &glyphPath,
+                          readFromStack,
+                          FALSE /* doConditionalLastRead */ );
+            }
+            continue;
 
+          case cf2_escFLEX:
+            {
+              static const FT_Bool  readFromStack[12] =
+              {
+                TRUE /* dx1 */, TRUE /* dy1 */,
+                TRUE /* dx2 */, TRUE /* dy2 */,
+                TRUE /* dx3 */, TRUE /* dy3 */,
+                TRUE /* dx4 */, TRUE /* dy4 */,
+                TRUE /* dx5 */, TRUE /* dy5 */,
+                TRUE /* dx6 */, TRUE /* dy6 */
+              };
 
-              FT_TRACE4(( " and\n" ));
 
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
+              FT_TRACE4(( " flex\n" ));
 
-              cf2_stack_pushInt( opStack, arg1 && arg2 );
+              cf2_doFlex( opStack,
+                          &curX,
+                          &curY,
+                          &glyphPath,
+                          readFromStack,
+                          FALSE /* doConditionalLastRead */ );
             }
-            continue; /* do not clear the stack */
+            break;      /* TODO: why is this not a continue? */
 
-          case cf2_escOR:
+          case cf2_escHFLEX1:
             {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-
+              static const FT_Bool  readFromStack[12] =
+              {
+                TRUE /* dx1 */, TRUE  /* dy1 */,
+                TRUE /* dx2 */, TRUE  /* dy2 */,
+                TRUE /* dx3 */, FALSE /* dy3 */,
+                TRUE /* dx4 */, FALSE /* dy4 */,
+                TRUE /* dx5 */, TRUE  /* dy5 */,
+                TRUE /* dx6 */, FALSE /* dy6 */
+              };
 
-              FT_TRACE4(( " or\n" ));
 
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
+              FT_TRACE4(( " hflex1\n" ));
 
-              cf2_stack_pushInt( opStack, arg1 || arg2 );
+              cf2_doFlex( opStack,
+                          &curX,
+                          &curY,
+                          &glyphPath,
+                          readFromStack,
+                          FALSE /* doConditionalLastRead */ );
             }
-            continue; /* do not clear the stack */
+            continue;
 
-          case cf2_escNOT:
+          case cf2_escFLEX1:
             {
-              CF2_F16Dot16  arg;
-
+              static const FT_Bool  readFromStack[12] =
+              {
+                TRUE  /* dx1 */, TRUE  /* dy1 */,
+                TRUE  /* dx2 */, TRUE  /* dy2 */,
+                TRUE  /* dx3 */, TRUE  /* dy3 */,
+                TRUE  /* dx4 */, TRUE  /* dy4 */,
+                TRUE  /* dx5 */, TRUE  /* dy5 */,
+                FALSE /* dx6 */, FALSE /* dy6 */
+              };
 
-              FT_TRACE4(( " not\n" ));
 
-              arg = cf2_stack_popFixed( opStack );
+              FT_TRACE4(( " flex1\n" ));
 
-              cf2_stack_pushInt( opStack, !arg );
+              cf2_doFlex( opStack,
+                          &curX,
+                          &curY,
+                          &glyphPath,
+                          readFromStack,
+                          TRUE /* doConditionalLastRead */ );
             }
-            continue; /* do not clear the stack */
+            continue;
 
-          case cf2_escABS:
+          /* these opcodes are reserved in both CFF & CFF2 */
+          case cf2_escRESERVED_1:
+          case cf2_escRESERVED_2:
+          case cf2_escRESERVED_6:
+          case cf2_escRESERVED_7:
+          case cf2_escRESERVED_8:
+          case cf2_escRESERVED_13:
+          case cf2_escRESERVED_16:
+          case cf2_escRESERVED_17:
+          case cf2_escRESERVED_19:
+          case cf2_escRESERVED_25:
+          case cf2_escRESERVED_31:
+          case cf2_escRESERVED_32:
+          case cf2_escRESERVED_33:
+            FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+            break;
+
+          default:
             {
-              CF2_F16Dot16  arg;
+              if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 )
+                FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+              else
+              {
+                /* second switch for 2-byte operators handles just CFF */
+                switch ( op2 )
+                {
 
+                case cf2_escDOTSECTION:
+                  /* something about `flip type of locking' -- ignore it */
+                  FT_TRACE4(( " dotsection\n" ));
 
-              FT_TRACE4(( " abs\n" ));
+                  break;
 
-              arg = cf2_stack_popFixed( opStack );
+                case cf2_escAND:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
 
-              cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
-            }
-            continue; /* do not clear the stack */
 
-          case cf2_escADD:
-            {
-              CF2_F16Dot16  summand1;
-              CF2_F16Dot16  summand2;
+                    FT_TRACE4(( " and\n" ));
 
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
 
-              FT_TRACE4(( " add\n" ));
+                    cf2_stack_pushInt( opStack, arg1 && arg2 );
+                  }
+                  continue; /* do not clear the stack */
 
-              summand2 = cf2_stack_popFixed( opStack );
-              summand1 = cf2_stack_popFixed( opStack );
+                case cf2_escOR:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
 
-              cf2_stack_pushFixed( opStack, summand1 + summand2 );
-            }
-            continue; /* do not clear the stack */
 
-          case cf2_escSUB:
-            {
-              CF2_F16Dot16  minuend;
-              CF2_F16Dot16  subtrahend;
+                    FT_TRACE4(( " or\n" ));
 
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
 
-              FT_TRACE4(( " sub\n" ));
+                    cf2_stack_pushInt( opStack, arg1 || arg2 );
+                  }
+                  continue; /* do not clear the stack */
 
-              subtrahend = cf2_stack_popFixed( opStack );
-              minuend    = cf2_stack_popFixed( opStack );
+                case cf2_escNOT:
+                  {
+                    CF2_F16Dot16  arg;
 
-              cf2_stack_pushFixed( opStack, minuend - subtrahend );
-            }
-            continue; /* do not clear the stack */
 
-          case cf2_escDIV:
-            {
-              CF2_F16Dot16  dividend;
-              CF2_F16Dot16  divisor;
+                    FT_TRACE4(( " not\n" ));
 
+                    arg = cf2_stack_popFixed( opStack );
 
-              FT_TRACE4(( " div\n" ));
+                    cf2_stack_pushInt( opStack, !arg );
+                  }
+                  continue; /* do not clear the stack */
 
-              divisor  = cf2_stack_popFixed( opStack );
-              dividend = cf2_stack_popFixed( opStack );
+                case cf2_escABS:
+                  {
+                    CF2_F16Dot16  arg;
 
-              cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) );
-            }
-            continue; /* do not clear the stack */
 
-          case cf2_escNEG:
-            {
-              CF2_F16Dot16  arg;
+                    FT_TRACE4(( " abs\n" ));
 
+                    arg = cf2_stack_popFixed( opStack );
 
-              FT_TRACE4(( " neg\n" ));
+                    cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
+                  }
+                  continue; /* do not clear the stack */
 
-              arg = cf2_stack_popFixed( opStack );
+                case cf2_escADD:
+                  {
+                    CF2_F16Dot16  summand1;
+                    CF2_F16Dot16  summand2;
 
-              cf2_stack_pushFixed( opStack, -arg );
-            }
-            continue; /* do not clear the stack */
 
-          case cf2_escEQ:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
+                    FT_TRACE4(( " add\n" ));
 
+                    summand2 = cf2_stack_popFixed( opStack );
+                    summand1 = cf2_stack_popFixed( opStack );
 
-              FT_TRACE4(( " eq\n" ));
+                    cf2_stack_pushFixed( opStack, summand1 + summand2 );
+                  }
+                  continue; /* do not clear the stack */
 
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
+                case cf2_escSUB:
+                  {
+                    CF2_F16Dot16  minuend;
+                    CF2_F16Dot16  subtrahend;
 
-              cf2_stack_pushInt( opStack, arg1 == arg2 );
-            }
-            continue; /* do not clear the stack */
 
-          case cf2_escDROP:
-            FT_TRACE4(( " drop\n" ));
+                    FT_TRACE4(( " sub\n" ));
 
-            (void)cf2_stack_popFixed( opStack );
-            continue; /* do not clear the stack */
+                    subtrahend = cf2_stack_popFixed( opStack );
+                    minuend    = cf2_stack_popFixed( opStack );
 
-          case cf2_escPUT:
-            {
-              CF2_F16Dot16  val;
-              CF2_Int       idx;
+                    cf2_stack_pushFixed( opStack, minuend - subtrahend );
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escDIV:
+                  {
+                    CF2_F16Dot16  dividend;
+                    CF2_F16Dot16  divisor;
 
-              FT_TRACE4(( " put\n" ));
 
-              idx = cf2_stack_popInt( opStack );
-              val = cf2_stack_popFixed( opStack );
+                    FT_TRACE4(( " div\n" ));
 
-              if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
-                storage[idx] = val;
-            }
-            continue; /* do not clear the stack */
+                    divisor  = cf2_stack_popFixed( opStack );
+                    dividend = cf2_stack_popFixed( opStack );
 
-          case cf2_escGET:
-            {
-              CF2_Int  idx;
+                    cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor 
) );
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escNEG:
+                  {
+                    CF2_F16Dot16  arg;
 
-              FT_TRACE4(( " get\n" ));
 
-              idx = cf2_stack_popInt( opStack );
+                    FT_TRACE4(( " neg\n" ));
 
-              if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
-                cf2_stack_pushFixed( opStack, storage[idx] );
-            }
-            continue; /* do not clear the stack */
+                    arg = cf2_stack_popFixed( opStack );
 
-          case cf2_escIFELSE:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-              CF2_F16Dot16  cond1;
-              CF2_F16Dot16  cond2;
+                    cf2_stack_pushFixed( opStack, -arg );
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escEQ:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
 
-              FT_TRACE4(( " ifelse\n" ));
 
-              cond2 = cf2_stack_popFixed( opStack );
-              cond1 = cf2_stack_popFixed( opStack );
-              arg2  = cf2_stack_popFixed( opStack );
-              arg1  = cf2_stack_popFixed( opStack );
+                    FT_TRACE4(( " eq\n" ));
 
-              cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 );
-            }
-            continue; /* do not clear the stack */
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
 
-          case cf2_escRANDOM: /* in spec */
-            FT_TRACE4(( " random\n" ));
+                    cf2_stack_pushInt( opStack, arg1 == arg2 );
+                  }
+                  continue; /* do not clear the stack */
 
-            CF2_FIXME;
-            break;
+                case cf2_escDROP:
+                  FT_TRACE4(( " drop\n" ));
 
-          case cf2_escMUL:
-            {
-              CF2_F16Dot16  factor1;
-              CF2_F16Dot16  factor2;
+                  (void)cf2_stack_popFixed( opStack );
+                  continue; /* do not clear the stack */
 
+                case cf2_escPUT:
+                  {
+                    CF2_F16Dot16  val;
+                    CF2_Int       idx;
 
-              FT_TRACE4(( " mul\n" ));
 
-              factor2 = cf2_stack_popFixed( opStack );
-              factor1 = cf2_stack_popFixed( opStack );
+                    FT_TRACE4(( " put\n" ));
 
-              cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) );
-            }
-            continue; /* do not clear the stack */
+                    idx = cf2_stack_popInt( opStack );
+                    val = cf2_stack_popFixed( opStack );
 
-          case cf2_escSQRT:
-            {
-              CF2_F16Dot16  arg;
+                    if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
+                      storage[idx] = val;
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escGET:
+                  {
+                    CF2_Int  idx;
 
-              FT_TRACE4(( " sqrt\n" ));
 
-              arg = cf2_stack_popFixed( opStack );
-              if ( arg > 0 )
-              {
-                FT_Fixed  root = arg;
-                FT_Fixed  new_root;
+                    FT_TRACE4(( " get\n" ));
 
+                    idx = cf2_stack_popInt( opStack );
 
-                /* Babylonian method */
-                for (;;)
-                {
-                  new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
-                  if ( new_root == root )
-                    break;
-                  root = new_root;
-                }
-                arg = new_root;
-              }
-              else
-                arg = 0;
+                    if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
+                    cf2_stack_pushFixed( opStack, storage[idx] );
+                  }
+                  continue; /* do not clear the stack */
 
-              cf2_stack_pushFixed( opStack, arg );
-            }
-            continue; /* do not clear the stack */
+                case cf2_escIFELSE:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
+                    CF2_F16Dot16  cond1;
+                    CF2_F16Dot16  cond2;
 
-          case cf2_escDUP:
-            {
-              CF2_F16Dot16  arg;
 
+                    FT_TRACE4(( " ifelse\n" ));
 
-              FT_TRACE4(( " dup\n" ));
+                    cond2 = cf2_stack_popFixed( opStack );
+                    cond1 = cf2_stack_popFixed( opStack );
+                    arg2  = cf2_stack_popFixed( opStack );
+                    arg1  = cf2_stack_popFixed( opStack );
 
-              arg = cf2_stack_popFixed( opStack );
+                    cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 
);
+                  }
+                  continue; /* do not clear the stack */
 
-              cf2_stack_pushFixed( opStack, arg );
-              cf2_stack_pushFixed( opStack, arg );
-            }
-            continue; /* do not clear the stack */
+                case cf2_escRANDOM: /* in spec */
+                  FT_TRACE4(( " random\n" ));
 
-          case cf2_escEXCH:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
+                  CF2_FIXME;
+                  break;
 
+                case cf2_escMUL:
+                  {
+                    CF2_F16Dot16  factor1;
+                    CF2_F16Dot16  factor2;
 
-              FT_TRACE4(( " exch\n" ));
 
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
+                    FT_TRACE4(( " mul\n" ));
 
-              cf2_stack_pushFixed( opStack, arg2 );
-              cf2_stack_pushFixed( opStack, arg1 );
-            }
-            continue; /* do not clear the stack */
+                    factor2 = cf2_stack_popFixed( opStack );
+                    factor1 = cf2_stack_popFixed( opStack );
 
-          case cf2_escINDEX:
-            {
-              CF2_Int   idx;
-              CF2_UInt  size;
+                    cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 
) );
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escSQRT:
+                  {
+                    CF2_F16Dot16  arg;
 
-              FT_TRACE4(( " index\n" ));
 
-              idx  = cf2_stack_popInt( opStack );
-              size = cf2_stack_count( opStack );
+                    FT_TRACE4(( " sqrt\n" ));
 
-              if ( size > 0 )
-              {
-                /* for `cf2_stack_getReal', index 0 is bottom of stack */
-                CF2_UInt  gr_idx;
+                    arg = cf2_stack_popFixed( opStack );
+                    if ( arg > 0 )
+                    {
+                      FT_Fixed  root = arg;
+                      FT_Fixed  new_root;
 
 
-                if ( idx < 0 )
-                  gr_idx = size - 1;
-                else if ( (CF2_UInt)idx >= size )
-                  gr_idx = 0;
-                else
-                  gr_idx = size - 1 - (CF2_UInt)idx;
+                      /* Babylonian method */
+                      for (;;)
+                      {
+                        new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
+                        if ( new_root == root )
+                          break;
+                        root = new_root;
+                      }
+                      arg = new_root;
+                    }
+                    else
+                      arg = 0;
 
-                cf2_stack_pushFixed( opStack,
-                                     cf2_stack_getReal( opStack, gr_idx ) );
-              }
-            }
-            continue; /* do not clear the stack */
+                    cf2_stack_pushFixed( opStack, arg );
+                  }
+                  continue; /* do not clear the stack */
 
-          case cf2_escROLL:
-            {
-              CF2_Int  idx;
-              CF2_Int  count;
+                case cf2_escDUP:
+                  {
+                    CF2_F16Dot16  arg;
 
 
-              FT_TRACE4(( " roll\n" ));
+                    FT_TRACE4(( " dup\n" ));
 
-              idx   = cf2_stack_popInt( opStack );
-              count = cf2_stack_popInt( opStack );
+                    arg = cf2_stack_popFixed( opStack );
 
-              cf2_stack_roll( opStack, count, idx );
-            }
-            continue; /* do not clear the stack */
+                    cf2_stack_pushFixed( opStack, arg );
+                    cf2_stack_pushFixed( opStack, arg );
+                  }
+                  continue; /* do not clear the stack */
 
-          case cf2_escHFLEX:
-            {
-              static const FT_Bool  readFromStack[12] =
-              {
-                TRUE /* dx1 */, FALSE /* dy1 */,
-                TRUE /* dx2 */, TRUE  /* dy2 */,
-                TRUE /* dx3 */, FALSE /* dy3 */,
-                TRUE /* dx4 */, FALSE /* dy4 */,
-                TRUE /* dx5 */, FALSE /* dy5 */,
-                TRUE /* dx6 */, FALSE /* dy6 */
-              };
+                case cf2_escEXCH:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
 
 
-              FT_TRACE4(( " hflex\n" ));
+                    FT_TRACE4(( " exch\n" ));
 
-              cf2_doFlex( opStack,
-                          &curX,
-                          &curY,
-                          &glyphPath,
-                          readFromStack,
-                          FALSE /* doConditionalLastRead */ );
-            }
-            continue;
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
 
-          case cf2_escFLEX:
-            {
-              static const FT_Bool  readFromStack[12] =
-              {
-                TRUE /* dx1 */, TRUE /* dy1 */,
-                TRUE /* dx2 */, TRUE /* dy2 */,
-                TRUE /* dx3 */, TRUE /* dy3 */,
-                TRUE /* dx4 */, TRUE /* dy4 */,
-                TRUE /* dx5 */, TRUE /* dy5 */,
-                TRUE /* dx6 */, TRUE /* dy6 */
-              };
+                    cf2_stack_pushFixed( opStack, arg2 );
+                    cf2_stack_pushFixed( opStack, arg1 );
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escINDEX:
+                  {
+                    CF2_Int   idx;
+                    CF2_UInt  size;
 
-              FT_TRACE4(( " flex\n" ));
 
-              cf2_doFlex( opStack,
-                          &curX,
-                          &curY,
-                          &glyphPath,
-                          readFromStack,
-                          FALSE /* doConditionalLastRead */ );
-            }
-            break;      /* TODO: why is this not a continue? */
+                    FT_TRACE4(( " index\n" ));
 
-          case cf2_escHFLEX1:
-            {
-              static const FT_Bool  readFromStack[12] =
-              {
-                TRUE /* dx1 */, TRUE  /* dy1 */,
-                TRUE /* dx2 */, TRUE  /* dy2 */,
-                TRUE /* dx3 */, FALSE /* dy3 */,
-                TRUE /* dx4 */, FALSE /* dy4 */,
-                TRUE /* dx5 */, TRUE  /* dy5 */,
-                TRUE /* dx6 */, FALSE /* dy6 */
-              };
+                    idx  = cf2_stack_popInt( opStack );
+                    size = cf2_stack_count( opStack );
 
+                    if ( size > 0 )
+                    {
+                      /* for `cf2_stack_getReal', index 0 is bottom of stack */
+                      CF2_UInt  gr_idx;
 
-              FT_TRACE4(( " hflex1\n" ));
 
-              cf2_doFlex( opStack,
-                          &curX,
-                          &curY,
-                          &glyphPath,
-                          readFromStack,
-                          FALSE /* doConditionalLastRead */ );
-            }
-            continue;
+                      if ( idx < 0 )
+                        gr_idx = size - 1;
+                      else if ( (CF2_UInt)idx >= size )
+                        gr_idx = 0;
+                      else
+                        gr_idx = size - 1 - (CF2_UInt)idx;
 
-          case cf2_escFLEX1:
-            {
-              static const FT_Bool  readFromStack[12] =
-              {
-                TRUE  /* dx1 */, TRUE  /* dy1 */,
-                TRUE  /* dx2 */, TRUE  /* dy2 */,
-                TRUE  /* dx3 */, TRUE  /* dy3 */,
-                TRUE  /* dx4 */, TRUE  /* dy4 */,
-                TRUE  /* dx5 */, TRUE  /* dy5 */,
-                FALSE /* dx6 */, FALSE /* dy6 */
-              };
+                      cf2_stack_pushFixed( opStack,
+                                           cf2_stack_getReal( opStack, gr_idx 
) );
+                    }
+                  }
+                  continue; /* do not clear the stack */
 
+                case cf2_escROLL:
+                  {
+                    CF2_Int  idx;
+                    CF2_Int  count;
 
-              FT_TRACE4(( " flex1\n" ));
 
-              cf2_doFlex( opStack,
-                          &curX,
-                          &curY,
-                          &glyphPath,
-                          readFromStack,
-                          TRUE /* doConditionalLastRead */ );
-            }
-            continue;
+                    FT_TRACE4(( " roll\n" ));
 
-          case cf2_escRESERVED_1:
-          case cf2_escRESERVED_2:
-          case cf2_escRESERVED_6:
-          case cf2_escRESERVED_7:
-          case cf2_escRESERVED_8:
-          case cf2_escRESERVED_13:
-          case cf2_escRESERVED_16:
-          case cf2_escRESERVED_17:
-          case cf2_escRESERVED_19:
-          case cf2_escRESERVED_25:
-          case cf2_escRESERVED_31:
-          case cf2_escRESERVED_32:
-          case cf2_escRESERVED_33:
-          default:
-            FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+                    idx   = cf2_stack_popInt( opStack );
+                    count = cf2_stack_popInt( opStack );
 
-          }; /* end of switch statement checking `op2' */
+                    cf2_stack_roll( opStack, count, idx );
+                  }
+                  continue; /* do not clear the stack */
 
-        } /* case cf2_cmdESC */
-        break;
+                } /* end of 2nd switch checking op2 */
+              }
+            }
+          };    /* end of 1st switch checking op2 */
+        }       /* case cf2_cmdESC */
+        break;  /* break switch checking op1 */
 
       case cf2_cmdENDCHAR:
         FT_TRACE4(( " endchar\n" ));
@@ -1820,6 +1851,9 @@
     /* check whether last error seen is also the first one */
     cf2_setError( error, lastError );
 
+    if ( *error )
+      FT_TRACE4(( "charstring error %d\n", *error ));
+
     /* free resources from objects we've used */
     cf2_glyphpath_finalize( &glyphPath );
     cf2_arrstack_finalize( &vStemHintArray );



reply via email to

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