Exemple #1
0
        private Type1Token ReadNextToken()
        {
            previousToken = CurrentToken;
            bool skip;

            do
            {
                skip = false;
                while (bytes.MoveNext())
                {
                    var b = bytes.CurrentByte;
                    var c = (char)b;

                    switch (c)
                    {
                    case '%':
                        comments.Add(ReadComment());
                        break;

                    case '(':
                        return(ReadString());

                    case ')':
                        throw new InvalidOperationException("Encountered an end of string ')' outside of string.");

                    case '[':
                        return(new Type1Token(c, Type1Token.TokenType.StartArray));

                    case ']':
                        return(new Type1Token(c, Type1Token.TokenType.EndArray));

                    case '{':
                        return(new Type1Token(c, Type1Token.TokenType.StartProc));

                    case '}':
                        return(new Type1Token(c, Type1Token.TokenType.EndProc));

                    case '/':
                    {
                        var name = ReadLiteral();
                        return(new Type1Token(name, Type1Token.TokenType.Literal));
                    }

                    case '<':
                    {
                        var following = bytes.Peek();
                        if (following == '<')
                        {
                            bytes.MoveNext();
                            return(new Type1Token("<<", Type1Token.TokenType.StartDict));
                        }

                        return(new Type1Token(c, Type1Token.TokenType.Name));
                    }

                    case '>':
                    {
                        var following = bytes.Peek();
                        if (following == '>')
                        {
                            bytes.MoveNext();
                            return(new Type1Token(">>", Type1Token.TokenType.EndDict));
                        }

                        return(new Type1Token(c, Type1Token.TokenType.Name));
                    }

                    default:
                    {
                        if (ReadHelper.IsWhitespace(b))
                        {
                            skip = true;
                            break;
                        }

                        if (b == 0)
                        {
                            skip = true;
                            break;
                        }

                        if (TryReadNumber(c, out var number))
                        {
                            return(number);
                        }

                        var name = ReadLiteral(c);
                        if (name == null)
                        {
                            throw new InvalidOperationException($"The binary portion of the type 1 font was invalid at position {bytes.CurrentOffset}.");
                        }

                        if (name.Equals(Type1Symbols.RdProcedure, StringComparison.OrdinalIgnoreCase) || name.Equals(Type1Symbols.RdProcedureAlt))
                        {
                            if (previousToken.Type == Type1Token.TokenType.Integer)
                            {
                                return(ReadCharString(previousToken.AsInt()));
                            }

                            throw new InvalidOperationException($"Expected integer token before {name} at offset {bytes.CurrentOffset}.");
                        }

                        return(new Type1Token(name, Type1Token.TokenType.Name));
                    }
                    }
                }
            } while (skip);

            return(null);
        }
Exemple #2
0
 public Type1Tokenizer(IInputBytes bytes)
 {
     this.bytes   = bytes;
     comments     = new List <string>();
     CurrentToken = ReadNextToken();
 }
Exemple #3
0
 public Type1Token GetNext()
 {
     CurrentToken = ReadNextToken();
     return(CurrentToken);
 }
Exemple #4
0
        private bool TryReadNumber(char c, out Type1Token numberToken)
        {
            char GetNext()
            {
                bytes.MoveNext();
                return((char)bytes.CurrentByte);
            }

            numberToken = null;

            var currentPosition = bytes.CurrentOffset;

            var           sb    = new StringBuilder();
            StringBuilder radix = null;

            var hasDigit = false;

            // optional + or -
            if (c == '+' || c == '-')
            {
                sb.Append(c);
                c = GetNext();
            }

            // optional digits
            while (char.IsDigit(c))
            {
                sb.Append(c);
                c        = GetNext();
                hasDigit = true;
            }

            // optional .
            if (c == '.')
            {
                sb.Append(c);
                c = GetNext();
            }
            else if (c == '#')
            {
                // PostScript radix number takes the form base#number
                radix = sb;
                sb    = new StringBuilder();
                c     = GetNext();
            }
            else if (sb.Length == 0 || !hasDigit)
            {
                // failure
                bytes.Seek(currentPosition);
                return(false);
            }
            else
            {
                // integer
                bytes.Seek(bytes.CurrentOffset - 1);

                numberToken = new Type1Token(sb.ToString(), Type1Token.TokenType.Integer);
                return(true);
            }

            // required digit
            if (char.IsDigit(c))
            {
                sb.Append(c);
                c = GetNext();
            }
            else
            {
                bytes.Seek(currentPosition);
                return(false);
            }

            // optional digits
            while (char.IsDigit(c))
            {
                sb.Append(c);
                c = GetNext();
            }

            // optional E
            if (c == 'E')
            {
                sb.Append(c);
                c = GetNext();

                // optional minus
                if (c == '-')
                {
                    sb.Append(c);
                    c = GetNext();
                }

                // required digit
                if (char.IsDigit(c))
                {
                    sb.Append(c);
                    c = GetNext();
                }
                else
                {
                    bytes.Seek(currentPosition);
                    return(false);
                }

                // optional digits
                while (char.IsDigit(c))
                {
                    sb.Append(c);
                    c = GetNext();
                }
            }

            bytes.Seek(bytes.CurrentOffset - 1);
            if (radix != null)
            {
                var number = Convert.ToInt32(sb.ToString(), int.Parse(radix.ToString(), CultureInfo.InvariantCulture));
                numberToken = new Type1Token(number.ToString(), Type1Token.TokenType.Integer);
            }
            else
            {
                numberToken = new Type1Token(sb.ToString(), Type1Token.TokenType.Real);
            }

            return(true);
        }