| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056 |
- // 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 ([email protected])
- //
- // 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
- }
- }
|