public static int ParseOperand(FontParser parser, int b0) { if (b0 == 28) { return(parser.ReadInt16()); } if (b0 == 29) { return(parser.ReadInt32()); } if (b0 == 30) { // A floating point value which we really don't need - skipping! while (true) { byte b = parser.ReadByte(); int n1 = b >> 4; int n2 = b & 15; if (n1 == 15 || n2 == 15) { break; } } return(0); } if (b0 >= 32 && b0 <= 246) { return(b0 - 139); } if (b0 >= 247 && b0 <= 250) { return((b0 - 247) * 256 + parser.ReadByte() + 108); } if (b0 >= 251 && b0 <= 254) { return(-(b0 - 251) * 256 - parser.ReadByte() - 108); } return(0); }
private void Parse(int start, int codeLength) { // Seek there now: Parser.Position = start; // Where should the parser quit? int max = start + codeLength; float c1x; float c1y; float c2x; float c2y; int subIndex; CffSubPosition subCode; // For each bytecode.. while (Parser.Position < max) { // Grab the byte: byte v = Parser.ReadByte(); switch (v) { case 1: // hstem ParseStems(); break; case 3: // vstem ParseStems(); break; case 4: // vmoveto if (Stack.Length > 1 && !HasWidth) { Width = Stack.Shift() + NominalWidthX; HasWidth = true; } Y += Stack.Shift(); Glyph.ClosePath(); // Move: Glyph.MoveTo(X * ScaleRatio, Y * ScaleRatio); break; case 5: // rlineto while (Stack.Length > 0) { X += Stack.Shift(); Y += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); } break; case 6: // hlineto while (Stack.Length > 0) { X += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); if (Stack.Empty) { break; } Y += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); } break; case 7: // vlineto while (Stack.Length > 0) { Y += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); if (Stack.Length == 0) { break; } X += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); } break; case 8: // rrcurveto while (Stack.Length > 0) { c1x = X + Stack.Shift(); c1y = Y + Stack.Shift(); c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x + Stack.Shift(); Y = c2y + Stack.Shift(); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); } break; case 10: // callsubr subIndex = (int)Stack.Pop() + SubrsBias; subCode = Subrs[subIndex]; if (subCode != null) { // Cache the position: subIndex = Parser.Position; // Parse: Parse(subCode.Position, subCode.Length); // Re-apply: Parser.Position = subIndex; } break; case 11: // return return; case 12: // escape v = Parser.ReadByte(); break; case 14: // endchar if (Stack.Length > 0 && !HasWidth) { Width = Stack.Shift() + NominalWidthX; HasWidth = true; } // Close the glyph: Glyph.ClosePath(); break; case 18: // hstemhm ParseStems(); break; case 19: // hintmask case 20: // cntrmask ParseStems(); Parser.Position += (NStems + 7) >> 3; break; case 21: // rmoveto if (Stack.Length > 2 && !HasWidth) { Width = Stack.Shift() + NominalWidthX; HasWidth = true; } X += Stack.Shift(); Y += Stack.Shift(); Glyph.ClosePath(); // Move now: Glyph.MoveTo(X * ScaleRatio, Y * ScaleRatio); break; case 22: // hmoveto if (Stack.Length > 1 && !HasWidth) { Width = Stack.Shift() + NominalWidthX; HasWidth = true; } X += Stack.Shift(); Glyph.ClosePath(); // Move now: Glyph.MoveTo(X * ScaleRatio, Y * ScaleRatio); break; case 23: // vstemhm ParseStems(); break; case 24: // rcurveline while (Stack.Length > 2) { c1x = X + Stack.Shift(); c1y = Y + Stack.Shift(); c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x + Stack.Shift(); Y = c2y + Stack.Shift(); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); } X += Stack.Shift(); Y += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); break; case 25: // rlinecurve while (Stack.Length > 6) { X += Stack.Shift(); Y += Stack.Shift(); Glyph.LineTo(X * ScaleRatio, Y * ScaleRatio); } c1x = X + Stack.Shift(); c1y = Y + Stack.Shift(); c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x + Stack.Shift(); Y = c2y + Stack.Shift(); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); break; case 26: // vvcurveto if (Stack.IsOdd) { X += Stack.Shift(); } while (Stack.Length > 0) { c1x = X; c1y = Y + Stack.Shift(); c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x; Y = c2y + Stack.Shift(); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); } break; case 27: // hhcurveto if (Stack.IsOdd) { Y += Stack.Shift(); } while (Stack.Length > 0) { c1x = X + Stack.Shift(); c1y = Y; c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x + Stack.Shift(); Y = c2y; Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); } break; case 28: // shortint Stack.Push(Parser.ReadInt16()); break; case 29: // callgsubr subIndex = (int)Stack.Pop() + GsubrsBias; subCode = GSubrs[subIndex]; if (subCode != null) { // Cache the position: subIndex = Parser.Position; // Parse: Parse(subCode.Position, subCode.Length); // Re-apply: Parser.Position = subIndex; } break; case 30: // vhcurveto while (Stack.Length > 0) { c1x = X; c1y = Y + Stack.Shift(); c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x + Stack.Shift(); Y = c2y + (Stack.Length == 1?Stack.Shift():0); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); if (Stack.Empty) { break; } c1x = X + Stack.Shift(); c1y = Y; c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); Y = c2y + Stack.Shift(); X = c2x + (Stack.Length == 1?Stack.Shift():0); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); } break; case 31: // hvcurveto while (Stack.Length > 0) { c1x = X + Stack.Shift(); c1y = Y; c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); Y = c2y + Stack.Shift(); X = c2x + (Stack.Length == 1 ? Stack.Shift() : 0); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); if (Stack.Empty) { break; } c1x = X; c1y = Y + Stack.Shift(); c2x = c1x + Stack.Shift(); c2y = c1y + Stack.Shift(); X = c2x + Stack.Shift(); Y = c2y + (Stack.Length == 1?Stack.Shift():0); Glyph.CurveTo(c1x * ScaleRatio, c1y * ScaleRatio, c2x * ScaleRatio, c2y * ScaleRatio, X * ScaleRatio, Y * ScaleRatio); } break; default: if (v < 32) { // Faulty operator. return; } else if (v < 247) { Stack.Push(v - 139); } else if (v < 251) { Stack.Push((v - 247) * 256 + Parser.ReadByte() + 108); } else if (v < 255) { Stack.Push(-(v - 251) * 256 - Parser.ReadByte() - 108); } else { Stack.Push((float)Parser.ReadInt32() / 65536f); } break; } } }
public static int ParseOperand(FontParser parser,int b0){ if(b0==28){ return parser.ReadInt16(); } if(b0==29){ return parser.ReadInt32(); } if(b0==30){ // A floating point value which we really don't need - skipping! while(true){ byte b=parser.ReadByte(); int n1 = b >> 4; int n2 = b & 15; if (n1 ==15 || n2==15) { break; } } return 0; } if (b0 >= 32 && b0 <= 246) { return b0 - 139; } if (b0 >= 247 && b0 <= 250) { return (b0 - 247) * 256 + parser.ReadByte() + 108; } if (b0 >= 251 && b0 <= 254) { return -(b0 - 251) * 256 - parser.ReadByte() - 108; } return 0; }