public Type2Instruction RemoveLast() { int last = _insts.Count - 1; Type2Instruction _lastInst = _insts[last]; _insts.RemoveAt(last); return(_lastInst); }
void dbugReExpandAndCompare_ForStep1(List <Type2Instruction> step1, List <Type2Instruction> org) { List <Type2Instruction> expand1 = new List <Type2Instruction>(org.Count); { int j = step1.Count; for (int i = 0; i < j; ++i) { Type2Instruction inst = step1[i]; switch ((OperatorName)inst.Op) { case OperatorName.LoadSbyte4: expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 24))); expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 16))); expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 8))); expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value))); break; case OperatorName.LoadSbyte3: expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 24))); expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 16))); expand1.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 8))); break; case OperatorName.LoadShort2: expand1.Add(new Type2Instruction(OperatorName.LoadInt, (short)(inst.Value >> 16))); expand1.Add(new Type2Instruction(OperatorName.LoadInt, (short)(inst.Value))); break; default: expand1.Add(inst); break; } } } //-------------------------------------------- if (expand1.Count != org.Count) { throw new NotSupportedException(); } else { //compare command-by-command int j = step1.Count; for (int i = 0; i < j; ++i) { Type2Instruction inst_exp = expand1[i]; Type2Instruction inst_org = org[i]; if (inst_exp.Op != inst_org.Op || inst_exp.Value != inst_org.Value) { throw new NotSupportedException(); } } } }
internal void ChangeFirstInstToGlyphWidthValue() { //check the first element must be loadint Type2Instruction firstInst = _insts[0]; if (!firstInst.IsLoadInt) { throw new NotSupportedException(); } //the replace _insts[0] = new Type2Instruction(OperatorName.GlyphWidth, firstInst.Value); }
internal void dbugDumpInstructionListToFile(string filename) { using (FileStream fs = new FileStream(filename, FileMode.Create)) using (StreamWriter w = new StreamWriter(fs)) { int j = insts.Count; for (int i = 0; i < j; ++i) { Type2Instruction inst = insts[i]; w.Write("[" + i + "] "); if (inst.Op == OperatorName.LoadInt) { w.Write(inst.Value.ToString()); w.Write(' '); } else { w.Write(inst.ToString()); w.WriteLine(); } } } }
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);//**** }
void dbugReExpandAndCompare_ForStep2(List <Type2Instruction> step2, List <Type2Instruction> org) { List <Type2Instruction> expand2 = new List <Type2Instruction>(org.Count); { int j = step2.Count; for (int i = 0; i < j; ++i) { Type2Instruction inst = step2[i]; //we use upper 2 bits to indicate that this is merged cmd or not byte merge_flags = (byte)(inst.Op >> 6); //lower 6 bits is actual cmd OperatorName onlyOpName = (OperatorName)(inst.Op & 0b111111); switch (onlyOpName) { case OperatorName.LoadSbyte4: expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 24))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 16))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 8))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value))); break; case OperatorName.LoadSbyte3: expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 24))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 16))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 8))); break; case OperatorName.LoadShort2: expand2.Add(new Type2Instruction(OperatorName.LoadInt, (short)(inst.Value >> 16))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (short)(inst.Value))); break; default: { switch (merge_flags) { case 0: expand2.Add(inst); break; case 1: expand2.Add(new Type2Instruction(OperatorName.LoadInt, inst.Value)); expand2.Add(new Type2Instruction(onlyOpName, 0)); break; case 2: expand2.Add(new Type2Instruction(OperatorName.LoadInt, (short)(inst.Value >> 16))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (short)(inst.Value))); expand2.Add(new Type2Instruction(onlyOpName, 0)); break; case 3: expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 24))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 16))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value >> 8))); expand2.Add(new Type2Instruction(OperatorName.LoadInt, (sbyte)(inst.Value))); expand2.Add(new Type2Instruction(onlyOpName, 0)); break; } } break; } } } //-------------------------------------------- if (expand2.Count != org.Count) { throw new NotSupportedException(); } else { //compare command-by-command int j = step2.Count; for (int i = 0; i < j; ++i) { Type2Instruction inst_exp = expand2[i]; Type2Instruction inst_org = org[i]; if (inst_exp.Op != inst_org.Op || inst_exp.Value != inst_org.Value) { throw new NotSupportedException(); } } } }
void CompactStep2MergeLoadIntWithNextCommand() { //a second pass //check if we can merge some load int( LoadInt, LoadSByte4, LoadShort2) except LoadSByte3 //to next instruction command or not int j = _step1List.Count; for (int i = 0; i < j; ++i) { Type2Instruction i0 = _step1List[i]; if (i + 1 < j) { //has next cmd byte merge_flags = IsLoadIntOrMergeableLoadIntExtension((OperatorName)i0.Op); if (merge_flags > 0) { Type2Instruction i1 = _step1List[i + 1]; //check i1 has empty space for i0 or not bool canbe_merged = false; switch ((OperatorName)i1.Op) { case OperatorName.LoadInt: case OperatorName.LoadShort2: case OperatorName.LoadSbyte4: case OperatorName.LoadSbyte3: case OperatorName.LoadFloat: case OperatorName.hintmask1: case OperatorName.hintmask2: case OperatorName.hintmask3: case OperatorName.hintmask4: case OperatorName.hintmask_bits: case OperatorName.cntrmask1: case OperatorName.cntrmask2: case OperatorName.cntrmask3: case OperatorName.cntrmask4: case OperatorName.cntrmask_bits: break; default: canbe_merged = true; break; } if (canbe_merged) { #if DEBUG if (merge_flags > 3) { throw new NotSupportedException(); } #endif _step2List.Add(new Type2Instruction((byte)((merge_flags << 6) | i1.Op), i0.Value)); i += 1; } else { _step2List.Add(i0); } } else { //this is the last one _step2List.Add(i0); } } else { //this is the last one _step2List.Add(i0); } } }
void CompactStep1OnlyLoadInt(List <Type2Instruction> insts) { int j = insts.Count; CompactRange _latestCompactRange = CompactRange.None; int startCollectAt = -1; int collecting_count = 0; void FlushWaitingNumbers() { //Nested method //flush waiting integer if (_latestCompactRange == CompactRange.Short) { switch (collecting_count) { default: throw new NotSupportedException(); case 0: break; //nothing case 2: _step1List.Add(new Type2Instruction(OperatorName.LoadShort2, (((ushort)insts[startCollectAt].Value) << 16) | (((ushort)insts[startCollectAt + 1].Value)) )); startCollectAt += 2; collecting_count -= 2; break; case 1: _step1List.Add(insts[startCollectAt]); startCollectAt += 1; collecting_count -= 1; break; } } else { switch (collecting_count) { default: throw new NotSupportedException(); case 0: break; //nothing case 4: { _step1List.Add(new Type2Instruction(OperatorName.LoadSbyte4, (((byte)insts[startCollectAt].Value) << 24) | (((byte)insts[startCollectAt + 1].Value) << 16) | (((byte)insts[startCollectAt + 2].Value) << 8) | (((byte)insts[startCollectAt + 3].Value) << 0) )); startCollectAt += 4; collecting_count -= 4; } break; case 3: _step1List.Add(new Type2Instruction(OperatorName.LoadSbyte3, (((byte)insts[startCollectAt].Value) << 24) | (((byte)insts[startCollectAt + 1].Value) << 16) | (((byte)insts[startCollectAt + 2].Value) << 8) )); startCollectAt += 3; collecting_count -= 3; break; case 2: _step1List.Add(new Type2Instruction(OperatorName.LoadShort2, (((ushort)insts[startCollectAt].Value) << 16) | ((ushort)insts[startCollectAt + 1].Value) )); startCollectAt += 2; collecting_count -= 2; break; case 1: _step1List.Add(insts[startCollectAt]); startCollectAt += 1; collecting_count -= 1; break; } } startCollectAt = -1; collecting_count = 0; } for (int i = 0; i < j; ++i) { Type2Instruction inst = insts[i]; if (inst.IsLoadInt) { //check waiting data in queue //get compact range CompactRange c1 = GetCompactRange(inst.Value); switch (c1) { default: throw new NotSupportedException(); case CompactRange.None: { } break; case CompactRange.SByte: { if (_latestCompactRange == CompactRange.Short) { FlushWaitingNumbers(); _latestCompactRange = CompactRange.SByte; } switch (collecting_count) { default: throw new NotSupportedException(); case 0: startCollectAt = i; _latestCompactRange = CompactRange.SByte; break; case 1: break; case 2: break; case 3: //we already have 3 bytes //so this is 4th byte collecting_count++; FlushWaitingNumbers(); continue; } collecting_count++; } break; case CompactRange.Short: { if (_latestCompactRange == CompactRange.SByte) { FlushWaitingNumbers(); _latestCompactRange = CompactRange.Short; } switch (collecting_count) { default: throw new NotSupportedException(); case 0: startCollectAt = i; _latestCompactRange = CompactRange.Short; break; case 1: //we already have 1 so this is 2nd collecting_count++; FlushWaitingNumbers(); continue; } collecting_count++; } break; } } else { //other cmds //flush waiting cmd if (collecting_count > 0) { FlushWaitingNumbers(); } _step1List.Add(inst); _latestCompactRange = CompactRange.None; } } }