void Run(IGlyphTranslator tx, Type2GlyphInstructionList instructionList, ref double currentX, ref double currentY) { //recursive *** Type2EvaluationStack evalStack = GetFreeEvalStack(); //** evalStack._currentX = currentX; evalStack._currentY = currentY; List <Type2Instruction> insts = instructionList.Insts; evalStack.GlyphTranslator = tx; int j = insts.Count; for (int i = 0; i < j; ++i) { Type2Instruction inst = insts[i]; //if (inst.Op != OperatorName.LoadInt) //{ //} switch (inst.Op) { default: throw new NotSupportedException(); case OperatorName.GlyphWidth: //TODO: break; case OperatorName.LoadInt: evalStack.Push(inst.Value); break; // case OperatorName.endchar: evalStack.EndChar(); break; case OperatorName.flex: evalStack.Flex(); break; case OperatorName.hflex: evalStack.H_Flex(); break; case OperatorName.hflex1: evalStack.H_Flex1(); break; case OperatorName.flex1: evalStack.Flex1(); break; //------------------------- //4.4: Arithmetic Operators case OperatorName.abs: evalStack.Op_Abs(); break; case OperatorName.add: evalStack.Op_Add(); break; case OperatorName.sub: evalStack.Op_Sub(); break; case OperatorName.div: evalStack.Op_Div(); break; case OperatorName.neg: evalStack.Op_Neg(); break; case OperatorName.random: evalStack.Op_Random(); break; case OperatorName.mul: evalStack.Op_Mul(); break; case OperatorName.sqrt: evalStack.Op_Sqrt(); break; case OperatorName.drop: evalStack.Op_Drop(); break; case OperatorName.exch: evalStack.Op_Exch(); break; case OperatorName.index: evalStack.Op_Index(); break; case OperatorName.roll: evalStack.Op_Roll(); break; case OperatorName.dup: evalStack.Op_Dup(); break; //------------------------- //4.5: Storage Operators case OperatorName.put: evalStack.Put(); break; case OperatorName.get: evalStack.Get(); break; //------------------------- //4.6: Conditional case OperatorName.and: evalStack.Op_And(); break; case OperatorName.or: evalStack.Op_Or(); break; case OperatorName.not: evalStack.Op_Not(); break; case OperatorName.eq: evalStack.Op_Eq(); break; case OperatorName.ifelse: evalStack.Op_IfElse(); break; // case OperatorName.rlineto: evalStack.R_LineTo(); break; case OperatorName.hlineto: evalStack.H_LineTo(); break; case OperatorName.vlineto: evalStack.V_LineTo(); break; case OperatorName.rrcurveto: evalStack.RR_CurveTo(); break; case OperatorName.hhcurveto: evalStack.HH_CurveTo(); break; case OperatorName.hvcurveto: evalStack.HV_CurveTo(); break; case OperatorName.rcurveline: evalStack.R_CurveLine(); break; case OperatorName.rlinecurve: evalStack.R_LineCurve(); break; case OperatorName.vhcurveto: evalStack.VH_CurveTo(); break; case OperatorName.vvcurveto: evalStack.VV_CurveTo(); break; //------------------------------------------------------------------- case OperatorName.rmoveto: evalStack.R_MoveTo(); break; case OperatorName.hmoveto: evalStack.H_MoveTo(); break; case OperatorName.vmoveto: evalStack.V_MoveTo(); break; //------------------------------------------------------------------- //4.3 Hint Operators case OperatorName.hstem: evalStack.H_Stem(); break; case OperatorName.vstem: evalStack.V_Stem(); break; case OperatorName.vstemhm: evalStack.V_StemHM(); break; case OperatorName.hstemhm: evalStack.H_StemHM(); break; //-------------------------- case OperatorName.hintmask1: evalStack.HintMask1(inst.Value); break; case OperatorName.hintmask2: evalStack.HintMask2(inst.Value); break; case OperatorName.hintmask3: evalStack.HintMask3(inst.Value); break; case OperatorName.hintmask4: evalStack.HintMask4(inst.Value); break; case OperatorName.hintmask_bits: evalStack.HintMaskBits(inst.Value); break; //------------------------------ case OperatorName.cntrmask1: evalStack.CounterSpaceMask1(inst.Value); break; case OperatorName.cntrmask2: evalStack.CounterSpaceMask2(inst.Value); break; case OperatorName.cntrmask3: evalStack.CounterSpaceMask3(inst.Value); break; case OperatorName.cntrmask4: evalStack.CounterSpaceMask4(inst.Value); break; case OperatorName.cntrmask_bits: evalStack.CounterSpaceMaskBits(inst.Value); break; //------------------------- //4.7: Subroutine Operators case OperatorName._return: { //*** //don't forget to return _evalStack's currentX, currentY to prev evl context currentX = evalStack._currentX; currentY = evalStack._currentY; evalStack.Ret(); } break; case OperatorName.callsubr: { //resolve local subrountine int rawSubRoutineNum = (int)evalStack.Pop(); Type2GlyphInstructionList resolvedSubroutine = _cff1Font._localSubrs[rawSubRoutineNum + _cffBias]; //then we move to another context //recursive *** Run(tx, resolvedSubroutine, ref evalStack._currentX, ref evalStack._currentY); } break; case OperatorName.callgsubr: throw new NotSupportedException(); } } ReleaseEvalStack(evalStack);//**** }