RTF.cs :  » 2.6.4-mono-.net-core » System.Windows.Forms » System » Windows » Forms » RTF » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Windows.Forms 
System.Windows.Forms » System » Windows » Forms » RTF » RTF.cs
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
//
// Authors:
//  Peter Bartok  (pbartok@novell.com)
//

// COMPLETE

#undef RTF_DEBUG

using System;
using System.Collections;
using System.IO;
using System.Text;

namespace System.Windows.Forms.RTF{
  internal class RTF {
    #region  Local Variables
    internal const char  EOF = unchecked((char)-1);
    internal const int  NoParam = -1000000;
    internal const int  DefaultEncodingCodePage = 1252;

    private TokenClass  rtf_class;
    private Major    major;
    private Minor    minor;
    private int    param;
    private string encoded_text;
    private Encoding encoding;
    private int encoding_code_page = DefaultEncodingCodePage;
    private StringBuilder  text_buffer;
    private Picture picture;
    private int    line_num;
    private int    line_pos;

    private char    pushed_char;
    //private StringBuilder  pushed_text_buffer;
    private TokenClass  pushed_class;
    private Major    pushed_major;
    private Minor    pushed_minor;
    private int    pushed_param;

    private char    prev_char;
    private bool    bump_line;

    private Font    font_list;

    private Charset    cur_charset;
    private Stack    charset_stack;

    private Style    styles;
    private Color    colors;
    private Font    fonts;

    private StreamReader  source;

    private static Hashtable  key_table;
    private static KeyStruct[]  Keys = KeysInit.Init();

    private DestinationCallback  destination_callbacks;
    private ClassCallback    class_callbacks;
    #endregion  // Local Variables

    #region Constructors
    static RTF() {
      key_table = new Hashtable(Keys.Length);
      for (int i = 0; i < Keys.Length; i++) {
        key_table[Keys[i].Symbol] = Keys[i];
      }
    }

    public RTF(Stream stream) {
      source = new StreamReader(stream);

      text_buffer = new StringBuilder(1024);
      //pushed_text_buffer = new StringBuilder(1024);

      rtf_class = TokenClass.None;
      pushed_class = TokenClass.None;
      pushed_char = unchecked((char)-1);

      line_num = 0;
      line_pos = 0;
      prev_char = unchecked((char)-1);
      bump_line = false;
      font_list = null;
      charset_stack = null;

      cur_charset = new Charset();

      destination_callbacks = new DestinationCallback();
      class_callbacks = new ClassCallback();

      destination_callbacks [Minor.OptDest] = new DestinationDelegate (HandleOptDest);
      destination_callbacks[Minor.FontTbl] = new DestinationDelegate(ReadFontTbl);
      destination_callbacks[Minor.ColorTbl] = new DestinationDelegate(ReadColorTbl);
      destination_callbacks[Minor.StyleSheet] = new DestinationDelegate(ReadStyleSheet);
      destination_callbacks[Minor.Info] = new DestinationDelegate(ReadInfoGroup);
      destination_callbacks[Minor.Pict] = new DestinationDelegate(ReadPictGroup);
      destination_callbacks[Minor.Object] = new DestinationDelegate(ReadObjGroup);
    }
    #endregion  // Constructors

    #region Properties
    public TokenClass TokenClass {
      get {
        return this.rtf_class;
      }

      set {
        this.rtf_class = value;
      }
    }

    public Major Major {
      get {
        return this.major;
      }

      set {
        this.major = value;
      }
    }

    public Minor Minor {
      get {
        return this.minor;
      }

      set {
        this.minor = value;
      }
    }

    public int Param {
      get {
        return this.param;
      }

      set {
        this.param = value;
      }
    }

    public string Text {
      get {
        return this.text_buffer.ToString();
      }

      set {
        if (value == null) {
          this.text_buffer.Length = 0;
        } else {
          this.text_buffer = new StringBuilder(value);
        }
      }
    }

    public string EncodedText {
      get { return encoded_text; }
    }

    public Picture Picture {
      get { return picture; }
      set { picture = value; }
    }

    public Color Colors {
      get {
        return colors;
      }

      set {
        colors = value;
      }
    }

    public Style Styles {
      get {
        return styles;
      }

      set {
        styles = value;
      }
    }

    public Font Fonts {
      get {
        return fonts;
      }

      set {
        fonts = value;
      }
    }

    public ClassCallback ClassCallback {
      get {
        return class_callbacks;
      }

      set {
        class_callbacks = value;
      }
    }

    public DestinationCallback DestinationCallback {
      get {
        return destination_callbacks;
      }

      set {
        destination_callbacks = value;
      }
    }

    public int LineNumber {
      get {
        return line_num;
      }
    }

    public int LinePos {
      get {
        return line_pos;
      }
    }
    #endregion  // Properties

    #region Methods
    /// <summary>Set the default font for documents without font table</summary>
    public void DefaultFont(string name) {
      Font font;

      font = new Font(this);
      font.Num = 0;
      font.Name = name;
    }

    /// <summary>Read the next character from the input - skip any crlf</summary>
    private char GetChar ()
    {
      return GetChar (true);
    }

    /// <summary>Read the next character from the input</summary>
    private char GetChar(bool skipCrLf) 
    {
      int  c;
      bool  old_bump_line;

SkipCRLF:
      if ((c = source.Read()) != -1) {
        this.text_buffer.Append((char) c);
      }

      if (this.prev_char == EOF) {
        this.bump_line = true;
      }

      old_bump_line = bump_line;
      bump_line = false;

      if (skipCrLf) {
        if (c == '\r') {
          bump_line = true;
          text_buffer.Length--;
          goto SkipCRLF;
        } else if (c == '\n') {
          bump_line = true;
          if (this.prev_char == '\r') {
            old_bump_line = false;
          }

          text_buffer.Length--;
          goto SkipCRLF;
        }
      }

      this.line_pos ++;
      if (old_bump_line) {
        this.line_num++;
        this.line_pos = 1;
      }

      this.prev_char = (char) c;
      return (char) c;
    }

    /// <summary>Parse the RTF stream</summary>
    public void Read() {
      while (GetToken() != TokenClass.EOF) {
        RouteToken();
      }
    }

    /// <summary>Route a token</summary>
    public void RouteToken() {

      if (CheckCM(TokenClass.Control, Major.Destination)) {
        DestinationDelegate d;

        d = destination_callbacks[minor];
        if (d != null) {
          d(this);
        }
      }

      // Invoke class callback if there is one
      ClassDelegate c;

      c = class_callbacks[rtf_class];
      if (c != null) {
        c(this);
      }
      
    }

    /// <summary>Skip to the end of the next group to start or current group we are in</summary>
    public void SkipGroup() {
      int  level;

      level = 1;

      while (GetToken() != TokenClass.EOF) {
        if (rtf_class == TokenClass.Group) {
          if (this.major == Major.BeginGroup) {
            level++;
          } else if (this.major == Major.EndGroup) {
            level--;
            if (level < 1) {
              break;
            }
          }
        }
      }
    }

    /// <summary>Return the next token in the stream</summary>
    public TokenClass GetToken() {
      if (pushed_class != TokenClass.None) {
        this.rtf_class = this.pushed_class;
        this.major = this.pushed_major;
        this.minor = this.pushed_minor;
        this.param = this.pushed_param;
        this.pushed_class = TokenClass.None;
        return this.rtf_class;
      }

      GetToken2();

      if (this.rtf_class == TokenClass.Text) {
        this.minor = (Minor)this.cur_charset[(int)this.major];
        if (encoding == null) {
          encoding = Encoding.GetEncoding (encoding_code_page);
        }
        encoded_text = new String (encoding.GetChars (new byte [] { (byte) this.major }));
      }

      if (this.cur_charset.Flags == CharsetFlags.None) {
        return this.rtf_class;
      }

      if (CheckCMM (TokenClass.Control, Major.Unicode, Minor.UnicodeAnsiCodepage)) {
        encoding_code_page = param;

        // fallback to the default one in case we have an invalid value
        if (encoding_code_page < 0 || encoding_code_page > 65535)
          encoding_code_page = DefaultEncodingCodePage;
      }

      if (((this.cur_charset.Flags & CharsetFlags.Read) != 0) && CheckCM(TokenClass.Control, Major.CharSet)) {
        this.cur_charset.ReadMap();
      } else if (((this.cur_charset.Flags & CharsetFlags.Switch) != 0) && CheckCMM(TokenClass.Control, Major.CharAttr, Minor.FontNum)) {
        Font  fp;

        fp = Font.GetFont(this.font_list, this.param);

        if (fp != null) {
          if (fp.Name.StartsWith("Symbol")) {
            this.cur_charset.ID = CharsetType.Symbol;
          } else {
            this.cur_charset.ID = CharsetType.General;
          }
        } else if (((this.cur_charset.Flags & CharsetFlags.Switch) != 0) && (this.rtf_class == TokenClass.Group)) {
          switch(this.major) {
            case Major.BeginGroup: {
              this.charset_stack.Push(this.cur_charset);
              break;
            }

            case Major.EndGroup: {
              this.cur_charset = (Charset)this.charset_stack.Pop();
              break;
            }
          }
        }
      }

      return this.rtf_class;
    }

    private void GetToken2() {
      char  c;
      int  sign;

      this.rtf_class = TokenClass.Unknown;
      this.param = NoParam;

      this.text_buffer.Length = 0;

      if (this.pushed_char != EOF) {
        c = this.pushed_char;
        this.text_buffer.Append(c);
        this.pushed_char = EOF;
      } else if ((c = GetChar()) == EOF) {
        this.rtf_class = TokenClass.EOF;
        return;
      }

      if (c == '{') {
        this.rtf_class = TokenClass.Group;
        this.major = Major.BeginGroup;
        return;
      }

      if (c == '}') {
        this.rtf_class = TokenClass.Group;
        this.major = Major.EndGroup;
        return;
      }

      if (c != '\\') {
        if (c != '\t') {
          this.rtf_class = TokenClass.Text;
          this.major = (Major)c;  // FIXME - typing?
          return;
        } else {
          this.rtf_class = TokenClass.Control;
          this.major = Major.SpecialChar;
          this.minor = Minor.Tab;
          return;
        }
      }

      if ((c = GetChar()) == EOF) {
        // Not so good
        return;
      }

      if (!Char.IsLetter(c)) {
        if (c == '\'') {
          char c2;

          if ((c = GetChar()) == EOF) {
            return;
          }

          if ((c2 = GetChar()) == EOF) {
            return;
          }

          this.rtf_class = TokenClass.Text;
          this.major = (Major)((Char)((Convert.ToByte(c.ToString(), 16) * 16 + Convert.ToByte(c2.ToString(), 16))));
          return;
        }

        // Escaped char
        if (c == ':' || c == '{' || c == '}' || c == '\\') {
          this.rtf_class = TokenClass.Text;
          this.major = (Major)c;
          return;
        }

        Lookup(this.text_buffer.ToString());
        return;
      }

      while (Char.IsLetter(c)) {
        if ((c = GetChar(false)) == EOF) {
          break;
        }
      }

      if (c != EOF) {
        this.text_buffer.Length--;
      }

      Lookup(this.text_buffer.ToString());

      if (c != EOF) {
        this.text_buffer.Append(c);
      }

      sign = 1;
      if (c == '-') {
        sign = -1;
        c = GetChar();
      }

      if (c != EOF && Char.IsDigit(c) && minor != Minor.PngBlip) {
        this.param = 0;
        while (Char.IsDigit(c)) {
          this.param = this.param * 10 + Convert.ToByte(c) - 48;
          if ((c = GetChar()) == EOF) {
            break;
          }
        }
        this.param *= sign;
      }

      if (c != EOF) {
        if (c != ' ' && c != '\r' && c != '\n') {
          this.pushed_char = c;
        }
        this.text_buffer.Length--;
      }
    }

    public void SetToken(TokenClass cl, Major maj, Minor min, int par, string text) {
      this.rtf_class = cl;
      this.major = maj;
      this.minor = min;
      this.param = par;
      if (par == NoParam) {
        this.text_buffer = new StringBuilder(text);
      } else {
        this.text_buffer = new StringBuilder(text + par.ToString());
      }
    }

    public void UngetToken() {
      if (this.pushed_class != TokenClass.None) {
        throw new RTFException(this, "Cannot unget more than one token");
      }

      if (this.rtf_class == TokenClass.None) {
        throw new RTFException(this, "No token to unget");
      }

      this.pushed_class = this.rtf_class;
      this.pushed_major = this.major;
      this.pushed_minor = this.minor;
      this.pushed_param = this.param;
      //this.pushed_text_buffer = new StringBuilder(this.text_buffer.ToString());
    }

    public TokenClass PeekToken() {
      GetToken();
      UngetToken();
      return rtf_class;
    }

    public void Lookup(string token) {
      Object    obj;
      KeyStruct  key;

      obj = key_table[token.Substring(1)];
      if (obj == null) {
        rtf_class = TokenClass.Unknown;
        major = (Major) -1;
        minor = (Minor) -1;
        return;
      }

      key = (KeyStruct)obj;
      this.rtf_class = TokenClass.Control;
      this.major = key.Major;
      this.minor = key.Minor;
    }

    public bool CheckCM(TokenClass rtf_class, Major major) {
      if ((this.rtf_class == rtf_class) && (this.major == major)) {
        return true;
      }

      return false;
    }

    public bool CheckCMM(TokenClass rtf_class, Major major, Minor minor) {
      if ((this.rtf_class == rtf_class) && (this.major == major) && (this.minor == minor)) {
        return true;
      }

      return false;
    }

    public bool CheckMM(Major major, Minor minor) {
      if ((this.major == major) && (this.minor == minor)) {
        return true;
      }

      return false;
    }
    #endregion  // Methods

    #region Default Delegates

    private void HandleOptDest (RTF rtf)
    {
      int group_levels = 1;

      while (true) {
        GetToken ();

        // Here is where we should handle recognised optional
        // destinations.
        //
        // Handle a picture group 
        //
        if (rtf.CheckCMM (TokenClass.Control, Major.Destination, Minor.Pict)) {
          ReadPictGroup (rtf);
          return;
        }

        if (rtf.CheckCM (TokenClass.Group, Major.EndGroup)) {
          if ((--group_levels) == 0) {
            break;
          }
        }

        if (rtf.CheckCM (TokenClass.Group, Major.BeginGroup)) {
          group_levels++;
        }
      }
    }

    private void ReadFontTbl(RTF rtf) {
      int  old;
      Font  font;

      old = -1;
      font = null;

      while (true) {
        rtf.GetToken();

        if (rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
          break;
        }

        if (old < 0) {
          if (rtf.CheckCMM(TokenClass.Control, Major.CharAttr, Minor.FontNum)) {
            old = 1;
          } else if (rtf.CheckCM(TokenClass.Group, Major.BeginGroup)) {
            old = 0;
          } else {
            throw new RTFException(rtf, "Cannot determine format");
          }
        }

        if (old == 0) {
          if (!rtf.CheckCM(TokenClass.Group, Major.BeginGroup)) {
            throw new RTFException(rtf, "missing \"{\"");
          }
          rtf.GetToken();
        }

        font = new Font(rtf);

        while ((rtf.rtf_class != TokenClass.EOF) && (!rtf.CheckCM(TokenClass.Text, (Major)';')) && (!rtf.CheckCM(TokenClass.Group, Major.EndGroup))) {
          if (rtf.rtf_class == TokenClass.Control) {
            switch(rtf.major) {
              case Major.FontFamily: {
                font.Family = (int)rtf.minor;
                break;
              }

              case Major.CharAttr: {
                switch(rtf.minor) {
                  case Minor.FontNum: {
                    font.Num = rtf.param;
                    break;
                  }

                  default: {
                    #if RTF_DEBUG
                      Console.WriteLine("Got unhandled Control.CharAttr.Minor: " + rtf.minor);
                    #endif
                    break;
                  }
                }
                break;
              }

              case Major.FontAttr: {
                switch (rtf.minor) {
                  case Minor.FontCharSet: {
                    font.Charset = (CharsetType)rtf.param;
                    break;
                  }

                  case Minor.FontPitch: {
                    font.Pitch = rtf.param;
                    break;
                  }

                  case Minor.FontCodePage: {
                    font.Codepage = rtf.param;
                    break;
                  }

                  case Minor.FTypeNil:
                  case Minor.FTypeTrueType: {
                    font.Type = rtf.param;
                    break;
                  }
                  default: {
                    #if RTF_DEBUG
                      Console.WriteLine("Got unhandled Control.FontAttr.Minor: " + rtf.minor);
                    #endif
                    break;
                  }
                }
                break;
              }

              default: {
                #if RTF_DEBUG
                  Console.WriteLine("ReadFontTbl: Unknown Control token " + rtf.major);
                #endif
                break;
              }
            }
          } else if (rtf.CheckCM(TokenClass.Group, Major.BeginGroup)) {
            rtf.SkipGroup();
          } else if (rtf.rtf_class == TokenClass.Text) {
            StringBuilder  sb;

            sb = new StringBuilder();

            while ((rtf.rtf_class != TokenClass.EOF) && (!rtf.CheckCM(TokenClass.Text, (Major)';')) && (!rtf.CheckCM(TokenClass.Group, Major.EndGroup)) && (!rtf.CheckCM(TokenClass.Group, Major.BeginGroup))) {
              sb.Append((char)rtf.major);
              rtf.GetToken();
            }

            if (rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
              rtf.UngetToken();
            }

            font.Name = sb.ToString();
            continue;
#if RTF_DEBUG
          } else {
            Console.WriteLine("ReadFontTbl: Unknown token " + rtf.text_buffer);
#endif
          }

          rtf.GetToken();
        }

        if (old == 0) {
          rtf.GetToken();

          if (!rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
            throw new RTFException(rtf, "Missing \"}\"");
          }
        }
      }

      if (font == null) {
        throw new RTFException(rtf, "No font created");
      }

      if (font.Num == -1) {
        throw new RTFException(rtf, "Missing font number");
      }

      rtf.RouteToken();
    }

    private void ReadColorTbl(RTF rtf) {
      Color  color;
      int  num;

      num = 0;

      while (true) {
        rtf.GetToken();

        if (rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
          break;
        }

        color = new Color(rtf);
        color.Num = num++;

        while (rtf.CheckCM(TokenClass.Control, Major.ColorName)) {
          switch (rtf.minor) {
            case Minor.Red: {
              color.Red = rtf.param;
              break;
            }

            case Minor.Green: {
              color.Green = rtf.param;
              break;
            }

            case Minor.Blue: {
              color.Blue = rtf.param;
              break;
            }
          }

          rtf.GetToken();
        }
        if (!rtf.CheckCM(TokenClass.Text, (Major)';')) {
          throw new RTFException(rtf, "Malformed color entry");
        }
      }
      rtf.RouteToken();
    }

    private void ReadStyleSheet(RTF rtf) {
      Style    style;
      StringBuilder  sb;

      sb = new StringBuilder();

      while (true) {
        rtf.GetToken();

        if (rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
          break;
        }

        style = new Style(rtf);

        if (!rtf.CheckCM(TokenClass.Group, Major.BeginGroup)) {
          throw new RTFException(rtf, "Missing \"{\"");
        }

        while (true) {
          rtf.GetToken();

          if ((rtf.rtf_class == TokenClass.EOF) || rtf.CheckCM(TokenClass.Text, (Major)';')) {
            break;
          }

          if (rtf.rtf_class == TokenClass.Control) {
            if (rtf.CheckMM(Major.ParAttr, Minor.StyleNum)) {
              style.Num = rtf.param;
              style.Type = StyleType.Paragraph;
              continue;
            }
            if (rtf.CheckMM(Major.CharAttr, Minor.CharStyleNum)) {
              style.Num = rtf.param;
              style.Type = StyleType.Character;
              continue;
            }
            if (rtf.CheckMM(Major.StyleAttr, Minor.SectStyleNum)) {
              style.Num = rtf.param;
              style.Type = StyleType.Section;
              continue;
            }
            if (rtf.CheckMM(Major.StyleAttr, Minor.BasedOn)) {
              style.BasedOn = rtf.param;
              continue;
            }
            if (rtf.CheckMM(Major.StyleAttr, Minor.Additive)) {
              style.Additive = true;
              continue;
            }
            if (rtf.CheckMM(Major.StyleAttr, Minor.Next)) {
              style.NextPar = rtf.param;
              continue;
            }

            new StyleElement(style, rtf.rtf_class, rtf.major, rtf.minor, rtf.param, rtf.text_buffer.ToString());
          } else if (rtf.CheckCM(TokenClass.Group, Major.BeginGroup)) {
            // This passes over "{\*\keycode ... }, among other things
            rtf.SkipGroup();
          } else if (rtf.rtf_class == TokenClass.Text) {
            while (rtf.rtf_class == TokenClass.Text) {
              if (rtf.major == (Major)';') {
                rtf.UngetToken();
                break;
              }

              sb.Append((char)rtf.major);
              rtf.GetToken();
            }

            style.Name = sb.ToString();
#if RTF_DEBUG
          } else {
            Console.WriteLine("ReadStyleSheet: Ignored token " + rtf.text_buffer);
#endif
          }
        }
        rtf.GetToken();

        if (!rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
          throw new RTFException(rtf, "Missing EndGroup (\"}\"");
        }

        // Sanity checks
        if (style.Name == null) {
          throw new RTFException(rtf, "Style must have name");
        }

        if (style.Num < 0) {
          if (!sb.ToString().StartsWith("Normal") && !sb.ToString().StartsWith("Standard")) {
            throw new RTFException(rtf, "Missing style number");
          }

          style.Num = Style.NormalStyleNum;
        }

        if (style.NextPar == -1) {
          style.NextPar = style.Num;
        }
      }

      rtf.RouteToken();
    }

    private void ReadInfoGroup(RTF rtf) {
      rtf.SkipGroup();
      rtf.RouteToken();
    }

    private void ReadPictGroup(RTF rtf)
    {
      bool read_image_data = false;

      Picture picture = new Picture ();
      while (true) {
        rtf.GetToken ();

        if (rtf.CheckCM (TokenClass.Group, Major.EndGroup))
          break;

        switch (minor) {
        case Minor.PngBlip:
          picture.ImageType = minor;
          read_image_data = true;
          break;
        case Minor.WinMetafile:
          picture.ImageType = minor;
          read_image_data = true;
          continue;
        case Minor.PicWid:
          continue;
        case Minor.PicHt:
          continue;
        case Minor.PicGoalWid:
          picture.SetWidthFromTwips (param);
          continue;
        case Minor.PicGoalHt:
          picture.SetHeightFromTwips (param);
          continue;
        }

        if (read_image_data && rtf.rtf_class == TokenClass.Text) {

          picture.Data.Seek (0, SeekOrigin.Begin);

          //char c = (char) rtf.major;

          uint digitValue1;
          uint digitValue2;
          char hexDigit1 = (char) rtf.major;
          char hexDigit2;

          while (true) {

            while (hexDigit1 == '\n' || hexDigit1 == '\r') {
              hexDigit1 = (char) source.Peek ();
              if (hexDigit1 == '}')
                break;
              hexDigit1 = (char) source.Read ();
            }
            
            hexDigit2 = (char) source.Peek ();
            if (hexDigit2 == '}')
              break;
            hexDigit2 = (char) source.Read ();
            while (hexDigit2 == '\n' || hexDigit2 == '\r') {
              hexDigit2 = (char) source.Peek ();
              if (hexDigit2 == '}')
                break;
              hexDigit2 = (char) source.Read ();
            }

            if (Char.IsDigit (hexDigit1))
              digitValue1 = (uint) (hexDigit1 - '0');
            else if (Char.IsLower (hexDigit1))
              digitValue1 = (uint) (hexDigit1 - 'a' + 10);
            else if (Char.IsUpper (hexDigit1))
              digitValue1 = (uint) (hexDigit1 - 'A' + 10);
            else if (hexDigit1 == '\n' || hexDigit1 == '\r')
              continue;
            else
              break;

            if (Char.IsDigit (hexDigit2))
              digitValue2 = (uint) (hexDigit2 - '0');
            else if (Char.IsLower (hexDigit2))
              digitValue2 = (uint) (hexDigit2 - 'a' + 10);
            else if (Char.IsUpper (hexDigit2))
              digitValue2 = (uint) (hexDigit2 - 'A' + 10);
            else if (hexDigit2 == '\n' || hexDigit2 == '\r')
              continue;
            else 
              break;

            picture.Data.WriteByte ((byte) checked (digitValue1 * 16 + digitValue2));

            // We get the first hex digit at the end, since in the very first
            // iteration we use rtf.major as the first hex digit
            hexDigit1 = (char) source.Peek ();
            if (hexDigit1 == '}')
              break;
            hexDigit1 = (char) source.Read ();
          }

          
          read_image_data = false;
          break;
        }
      }

      if (picture.ImageType != Minor.Undefined && !read_image_data) {
        this.picture = picture;
        SetToken (TokenClass.Control, Major.PictAttr, picture.ImageType, 0, String.Empty);
      }
    }

    private void ReadObjGroup(RTF rtf) {
      rtf.SkipGroup();
      rtf.RouteToken();
    }
    #endregion  // Default Delegates
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.