--- /dev/null
+// 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>
+//
+//
+
+// NOT COMPLETE
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.IO;
+using System.Text;
+using RTF=System.Windows.Forms.RTF;
+
+namespace System.Windows.Forms {
+ public class RichTextBox : TextBoxBase {
+ #region Local Variables
+ internal bool auto_word_select;
+ internal int bullet_indent;
+ internal bool can_redo;
+ internal bool detect_urls;
+ internal string redo_action_name;
+ internal int margin_right;
+ internal string undo_action_name;
+ internal float zoom;
+
+ private RTF.TextMap rtf_text_map;
+ private int rtf_skip_width;
+ private int rtf_skip_count;
+ private StringBuilder rtf_line;
+ private Font rtf_font;
+ private SolidBrush rtf_color;
+ private RTF.Font rtf_rtffont;
+ private int rtf_rtffont_size;
+ private FontStyle rtf_rtfstyle;
+ private HorizontalAlignment rtf_rtfalign;
+ private int rtf_cursor_x;
+ private int rtf_cursor_y;
+ #endregion // Local Variables
+
+ #region Public Constructors
+ public RichTextBox() {
+ accepts_return = true;
+ auto_word_select = false;
+ bullet_indent = 0;
+ can_redo = false;
+ detect_urls = true;
+ max_length = Int32.MaxValue;
+ redo_action_name = string.Empty;
+ margin_right = 0;
+ undo_action_name = string.Empty;
+ zoom = 1;
+ base.Multiline = true;
+ document.CRLFSize = 1;
+
+ scrollbars = RichTextBoxScrollBars.Both;
+ alignment = HorizontalAlignment.Left;
+ this.LostFocus +=new EventHandler(RichTextBox_LostFocus);
+ this.BackColor = ThemeEngine.Current.ColorWindow;
+ this.ForeColor = ThemeEngine.Current.ColorWindowText;
+
+ Console.WriteLine("A friendly request: Do not log a bug about debug messages being emitted when\n" +
+ "using RichTextBox. It's not yet finished, it will spew debug information, and\n" +
+ "it may not work the way you like it just yet. Some methods also are also not yet\n" +
+ "implemented. And we're also aware that text gets bolder with every change.");
+ Console.WriteLine("To quote Sean Gilkes: Patience is a virtue, waiting doesn't hurt you :-)");
+ }
+ #endregion // Public Constructors
+
+ #region Private & Internal Methods
+ private void RichTextBox_LostFocus(object sender, EventArgs e) {\r
+ has_focus = false;\r
+ Invalidate();\r
+ }\r
+ #endregion // Private & Internal Methods
+
+ #region Public Instance Properties
+ public override bool AllowDrop {\r
+ get {\r
+ return base.AllowDrop;\r
+ }\r
+\r
+ set {\r
+ base.AllowDrop = value;\r
+ }\r
+ }\r
+\r
+ [DefaultValue(false)]\r
+ public override bool AutoSize {\r
+ get {\r
+ return auto_size;\r
+ }\r
+\r
+ set {\r
+ base.AutoSize = value;\r
+ }\r
+ }\r
+\r
+ [DefaultValue(false)]\r
+ public bool AutoWordSelection {\r
+ get {\r
+ return auto_word_select;\r
+ }\r
+\r
+ set {\r
+ auto_word_select = true;\r
+ }\r
+ }\r
+\r
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override System.Drawing.Image BackgroundImage {\r
+ get {\r
+ return background_image;\r
+ }\r
+\r
+ set {\r
+ base.BackgroundImage = value;\r
+ }\r
+ }\r
+\r
+ [DefaultValue(0)]\r
+ [Localizable(true)]\r
+ public int BulletIndent {
+ get {
+ return bullet_indent;
+ }
+
+ set {
+ bullet_indent = value;
+ }
+ }
+
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public bool CanRedo {
+ get {
+ return can_redo;
+ }
+ }
+
+ [DefaultValue(true)]
+ public bool DetectUrls {
+ get {
+ return detect_urls;
+ }
+
+ set {
+ detect_urls = true;
+ }
+ }
+
+ public override Font Font {\r
+ get {\r
+ return base.Font;\r
+ }\r
+\r
+ set {\r
+ if (font != value) {\r
+ if (auto_size) {\r
+ if (PreferredHeight != Height) {
+ Height = PreferredHeight;
+ }
+ }\r
+\r
+ base.Font = value;\r
+ }\r
+ }\r
+ }\r
+
+ public override Color ForeColor {\r
+ get {\r
+ return base.ForeColor;\r
+ }\r
+\r
+ set {\r
+ base.ForeColor = value;\r
+ }\r
+ }\r
+
+ [DefaultValue(Int32.MaxValue)]
+ public override int MaxLength {\r
+ get {\r
+ return base.max_length;\r
+ }\r
+\r
+ set {\r
+ base.max_length = value;\r
+ }\r
+ }\r
+
+ [DefaultValue(true)]
+ public override bool Multiline {\r
+ get {\r
+ return multiline;\r
+ }\r
+\r
+ set {\r
+ base.Multiline = value;\r
+ }\r
+ }\r
+
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ [MonoTODO]
+ public string RedoActionName {
+ get {
+ return redo_action_name;
+ }
+ }
+
+ [DefaultValue(0)]
+ [Localizable(true)]
+ [MonoTODO("Teach TextControl.RecalculateLine to consider the right margin as well")]
+ public int RightMargin {
+ get {
+ return margin_right;
+ }
+
+ set {
+ margin_right = value;
+ }
+ }
+
+ [Browsable(false)]
+ [DefaultValue("")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ [MonoTODO("finish and plug in the rtf parser/generator")]
+ public string Rtf {
+ get {
+ // FIXME
+ return null;
+ }
+
+ set {
+ // FIXME
+ }
+ }
+
+ [DefaultValue(RichTextBoxScrollBars.Both)]
+ [Localizable(true)]
+ public RichTextBoxScrollBars ScrollBars {
+ get {
+ return scrollbars;
+ }
+
+ set {
+ scrollbars = value;
+ }
+ }
+
+ [MonoTODO("finish and plug in rtf parser/generator")]
+ public string SelectedRtf {
+ get {
+ // FIXME
+ return null;
+ }
+
+ set {
+ // FIXME
+ }
+ }
+
+ public override string SelectedText {\r
+ get {\r
+ return base.SelectedText;\r
+ }\r
+\r
+ set {\r
+ base.SelectedText = value;\r
+ }\r
+ }\r
+
+ [Browsable(false)]
+ [DefaultValue(HorizontalAlignment.Left)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public HorizontalAlignment SelectionAlignment {
+ get {
+ HorizontalAlignment align;
+ int line_no;
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart(document.selection_start.line);
+ align = start.alignment;
+ line_no = start.line_no;
+
+ end = document.ParagraphEnd(document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ if (line.alignment != align) {
+ return HorizontalAlignment.Left;
+ }
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine(line.line_no + 1);
+ }
+
+ return align;
+ }
+
+ set {
+ HorizontalAlignment align;
+ int line_no;
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart(document.selection_start.line);
+ line_no = start.line_no;
+
+ end = document.ParagraphEnd(document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ line.alignment = value;
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine(line.line_no + 1);
+ }
+ this.CalculateDocument();
+ }
+ }
+
+
+ public Font SelectionFont {
+ get {
+ Font font;
+ LineTag start;
+ LineTag end;
+ LineTag tag;
+
+ start = document.selection_start.tag;
+ end = document.selection_end.tag;
+ font = document.selection_start.tag.font;
+
+ tag = start;
+ while (true) {
+ if (!font.Equals(tag.font)) {
+ return null;
+ }
+
+ if (tag == end) {
+ break;
+ }
+
+ tag = document.NextTag(tag);
+
+ if (tag == null) {
+ break;
+ }
+ }
+
+ return font;
+ }
+
+ set {
+ int sel_start;
+ int sel_end;
+
+ sel_start = document.LineTagToCharIndex(document.selection_start.line, document.selection_start.pos);
+ sel_end = document.LineTagToCharIndex(document.selection_end.line, document.selection_end.pos);
+
+ document.FormatText(document.selection_start.line, document.selection_start.pos + 1, document.selection_end.line, document.selection_end.pos, value, document.selection_start.tag.color);
+
+ document.CharIndexToLineTag(sel_start, out document.selection_start.line, out document.selection_start.tag, out document.selection_start.pos);
+ document.CharIndexToLineTag(sel_end, out document.selection_end.line, out document.selection_end.tag, out document.selection_end.pos);
+
+ document.UpdateView(document.selection_start.line, 0);
+ document.AlignCaret();
+
+ }
+ }
+
+ [Localizable(true)]
+ public override string Text {\r
+ get {\r
+ return base.Text;\r
+ }\r
+\r
+ set {\r
+ base.Text = value;\r
+ }\r
+ }\r
+
+ [Browsable(false)]
+ public override int TextLength {\r
+ get {\r
+ return base.TextLength;\r
+ }\r
+ }\r
+
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public string UndoActionName {
+ get {
+ return undo_action_name;
+ }
+ }
+
+ [Localizable(true)]
+ [DefaultValue(1)]
+ public float ZoomFactor {
+ get {
+ return zoom;
+ }
+
+ set {
+ zoom = value;
+ }
+ }
+ #endregion // Public Instance Properties
+
+ #region Protected Instance Properties
+ protected override CreateParams CreateParams {\r
+ get {\r
+ return base.CreateParams;\r
+ }\r
+ }\r
+
+ protected override Size DefaultSize {\r
+ get {\r
+ return new Size(100, 96);\r
+ }\r
+ }\r
+ #endregion // Protected Instance Properties
+
+ #region Public Instance Methods
+ public void LoadFile(System.IO.Stream data, RichTextBoxStreamType fileType) {
+ RTF.RTF rtf; // Not 'using SWF.RTF' to avoid ambiguities with font and color
+
+ document.Empty();
+
+ // FIXME - ignoring unicode
+ if (fileType == RichTextBoxStreamType.PlainText) {
+ StringBuilder sb;\r
+ int count;\r
+ byte[] buffer;\r
+\r
+ try {\r
+ sb = new StringBuilder((int)data.Length);\r
+ buffer = new byte[1024];\r
+ }\r
+\r
+ catch {\r
+ throw new IOException("Not enough memory to load document");\r
+ return;\r
+ }\r
+\r
+ count = 0;\r
+ while (count < data.Length) {\r
+ count += data.Read(buffer, count, 1024);\r
+ sb.Append(buffer);\r
+ }\r
+ base.Text = sb.ToString();\r
+ return;\r
+ }\r
+
+
+ rtf = new RTF.RTF(data);
+
+ // Prepare
+ rtf.ClassCallback[RTF.TokenClass.Text] = new RTF.ClassDelegate(HandleText);
+ rtf.ClassCallback[RTF.TokenClass.Control] = new RTF.ClassDelegate(HandleControl);
+
+ rtf_skip_width = 0;
+ rtf_skip_count = 0;
+ rtf_line = new StringBuilder();
+ rtf_font = Font;
+ rtf_color = new SolidBrush(ForeColor);
+ rtf_rtffont_size = this.Font.Height;
+ rtf_rtfalign = HorizontalAlignment.Left;
+ rtf_rtffont = null;
+ rtf_cursor_x = 0;
+ rtf_cursor_y = 1;
+
+ rtf_text_map = new RTF.TextMap();
+ RTF.TextMap.SetupStandardTable(rtf_text_map.Table);
+
+ rtf.Read(); // That's it
+ document.RecalculateDocument(CreateGraphics());
+ }
+
+ public void LoadFile(string path) {
+ if (path.EndsWith(".rtf")) {
+ LoadFile(path, RichTextBoxStreamType.RichText);
+ } else {
+ LoadFile(path, RichTextBoxStreamType.PlainText);
+ }
+ }
+
+ public void LoadFile(string path, RichTextBoxStreamType fileType) {
+ FileStream data;
+
+ data = null;
+
+// try {
+ data = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 1024);
+ LoadFile(data, fileType);
+// }
+
+// catch {
+// throw new IOException("Could not open file " + path);
+// }
+
+// finally {
+ if (data != null) {
+ data.Close();
+// }
+ }
+ }
+
+ public void SaveFile(Stream data, RichTextBoxStreamType fileType) {
+ }
+
+ public void SaveFile(string path) {
+ if (path.EndsWith(".rtf")) {
+ SaveFile(path, RichTextBoxStreamType.RichText);
+ } else {
+ SaveFile(path, RichTextBoxStreamType.PlainText);
+ }
+ }
+
+ public void SaveFile(string path, RichTextBoxStreamType fileType) {
+ FileStream data;
+ Encoding encoding;
+
+ data = null;
+ if (fileType == RichTextBoxStreamType.UnicodePlainText) {
+ encoding = Encoding.Unicode;
+ } else {
+ encoding = Encoding.ASCII;
+ }
+
+ try {
+ data = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 1024, false);
+ SaveFile(data, fileType);
+ }
+
+ catch {
+ throw new IOException("Could not write document to file " + path);
+ }
+
+ finally {
+ if (data != null) {
+ data.Close();
+ }
+ }
+ }
+
+ #endregion // Public Instance Methods
+
+ #region Protected Instance Methods
+ protected override void OnBackColorChanged(EventArgs e) {\r
+ base.OnBackColorChanged (e);\r
+ }\r
+\r
+ protected override void OnContextMenuChanged(EventArgs e) {\r
+ base.OnContextMenuChanged (e);\r
+ }\r
+\r
+ protected override void OnHandleCreated(EventArgs e) {\r
+ base.OnHandleCreated (e);\r
+ }\r
+\r
+ protected override void OnHandleDestroyed(EventArgs e) {\r
+ base.OnHandleDestroyed (e);\r
+ }\r
+\r
+ protected override void OnRightToLeftChanged(EventArgs e) {\r
+ base.OnRightToLeftChanged (e);\r
+ }\r
+\r
+ protected override void OnSystemColorsChanged(EventArgs e) {\r
+ base.OnSystemColorsChanged (e);\r
+ }\r
+\r
+ protected override void OnTextChanged(EventArgs e) {\r
+ base.OnTextChanged (e);\r
+ }\r
+\r
+ protected override void WndProc(ref Message m) {\r
+ base.WndProc (ref m);\r
+ }\r
+ #endregion // Protected Instance Methods
+
+ #region Events
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandler BackgroundImageChanged;
+
+ public event ContentsResizedEventHandler ContentsResized;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandler DoubleClick;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event DragEventHandler DragDrop;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event DragEventHandler DragEnter;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandler DragLeave;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event DragEventHandler DragOver;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event GiveFeedbackEventHandler GiveFeedback;
+
+ public event EventHandler HScroll;
+ public event EventHandler ImeChange;
+ public event LinkClickedEventHandler LinkClicked;
+ public event EventHandler Protected;
+
+ [Browsable(false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event QueryContinueDragEventHandler QueryContinueDrag;
+ public event EventHandler SelectionChanged;
+ public event EventHandler VScroll;
+ #endregion // Events
+
+ #region Private Methods
+ void HandleControl(RTF.RTF rtf) {
+ switch(rtf.Major) {
+ case RTF.Major.Unicode: {
+ switch(rtf.Minor) {
+ case Minor.UnicodeCharBytes: {
+ rtf_skip_width = rtf.Param;
+ break;
+ }
+
+ case Minor.UnicodeChar: {
+ rtf_skip_count += rtf_skip_width;
+ rtf_line.Append((char)rtf.Param);
+ break;
+ }
+ }
+ break;
+ }
+
+ case RTF.Major.Destination: {
+ Console.Write("[Got Destination control {0}]", rtf.Minor);
+ rtf.SkipGroup();
+ break;
+ }
+
+ case RTF.Major.CharAttr: {
+ switch(rtf.Minor) {
+ case Minor.ForeColor: {
+ System.Windows.Forms.RTF.Color color;
+ int num;
+
+ color = System.Windows.Forms.RTF.Color.GetColor(rtf, rtf.Param);
+ if (color != null) {
+ FlushText(false);
+ if (color.Red == -1 && color.Green == -1 && color.Blue == -1) {
+ this.rtf_color = new SolidBrush(ForeColor);
+ } else {
+ this.rtf_color = new SolidBrush(Color.FromArgb(color.Red, color.Green, color.Blue));
+ }
+ }
+ break;
+ }
+
+ case Minor.FontSize: {
+ this.rtf_rtffont_size = rtf.Param / 2;
+ break;
+ }
+
+ case Minor.FontNum: {
+ System.Windows.Forms.RTF.Font font;
+
+ font = System.Windows.Forms.RTF.Font.GetFont(rtf, rtf.Param);
+ if (font != null) {
+ FlushText(false);
+ this.rtf_rtffont = font;
+ }
+ break;
+ }
+
+ case Minor.Plain: {
+ FlushText(false);
+ rtf_rtfstyle = FontStyle.Regular;
+ break;
+ }
+
+ case Minor.Bold: {
+ FlushText(false);
+ if (rtf.Param == RTF.RTF.NoParam) {
+ rtf_rtfstyle |= FontStyle.Bold;
+ } else {
+ rtf_rtfstyle &= ~FontStyle.Bold;
+ }
+ break;
+ }
+
+ case Minor.Italic: {
+ FlushText(false);
+ if (rtf.Param == RTF.RTF.NoParam) {
+ rtf_rtfstyle |= FontStyle.Italic;
+ } else {
+ rtf_rtfstyle &= ~FontStyle.Italic;
+ }
+ break;
+ }
+
+ case Minor.StrikeThru: {
+ FlushText(false);
+ if (rtf.Param == RTF.RTF.NoParam) {
+ rtf_rtfstyle |= FontStyle.Strikeout;
+ } else {
+ rtf_rtfstyle &= ~FontStyle.Strikeout;
+ }
+ break;
+ }
+
+ case Minor.Underline: {
+ FlushText(false);
+ if (rtf.Param == RTF.RTF.NoParam) {
+ rtf_rtfstyle |= FontStyle.Underline;
+ } else {
+ rtf_rtfstyle &= ~FontStyle.Underline;
+ }
+ break;
+ }
+
+ case Minor.NoUnderline: {
+ FlushText(false);
+ rtf_rtfstyle &= ~FontStyle.Underline;
+ break;
+ }
+ }
+ break;
+ }
+
+ case RTF.Major.SpecialChar: {
+ Console.Write("[Got SpecialChar control {0}]", rtf.Minor);
+ SpecialChar(rtf);
+ break;
+ }
+ }
+ }
+
+ void SpecialChar(RTF.RTF rtf) {
+ switch(rtf.Minor) {
+ case Minor.Page:
+ case Minor.Sect:
+ case Minor.Row:
+ case Minor.Line:
+ case Minor.Par: {
+ FlushText(true);
+ break;
+ }
+
+ case Minor.Cell: {
+ Console.Write(" ");
+ break;
+ }
+
+ case Minor.NoBrkSpace: {
+ Console.Write(" ");
+ break;
+ }
+
+ case Minor.Tab: {
+ Console.Write("\t");
+ break;
+ }
+
+ case Minor.NoBrkHyphen: {
+ Console.Write("-");
+ break;
+ }
+
+ case Minor.Bullet: {
+ Console.Write("*");
+ break;
+ }
+
+ case Minor.EmDash: {
+ Console.Write("\97");
+ break;
+ }
+
+ case Minor.EnDash: {
+ Console.Write("\96");
+ break;
+ }
+
+ case Minor.LQuote: {
+ Console.Write("\91");
+ break;
+ }
+
+ case Minor.RQuote: {
+ Console.Write("\92");
+ break;
+ }
+
+ case Minor.LDblQuote: {
+ Console.Write("\93");
+ break;
+ }
+
+ case Minor.RDblQuote: {
+ Console.Write("\94");
+ break;
+ }
+
+ default: {
+ rtf.SkipGroup();
+ break;
+ }
+ }
+ }
+
+
+ void HandleText(RTF.RTF rtf) {
+ if (rtf_skip_count > 0) {
+ rtf_skip_count--;
+ return;
+ }
+
+ if ((RTF.StandardCharCode)rtf.Minor != RTF.StandardCharCode.nothing) {
+ rtf_line.Append(rtf_text_map[(RTF.StandardCharCode)rtf.Minor]);
+ } else {
+ if ((int)rtf.Major > 31 && (int)rtf.Major < 128) {
+ rtf_line.Append((char)rtf.Major);
+ } else {
+ //rtf_line.Append((char)rtf.Major);
+ Console.Write("[Literal:0x{0:X2}]", (int)rtf.Major);
+ }
+ }
+ }
+
+ void FlushText(bool newline) {
+ int length;
+ Font font;
+
+ length = rtf_line.Length;
+ if (length == 0) {
+ return;
+ }
+
+ if (rtf_rtffont != null) {
+ font = new Font(rtf_rtffont.Name, rtf_rtffont_size, rtf_rtfstyle);
+ } else {
+ font = this.Font;
+ }
+
+ if (rtf_cursor_x == 0) {
+ document.Add(rtf_cursor_y, rtf_line.ToString(), rtf_rtfalign, font, rtf_color);
+ } else {
+ Line line;
+
+ line = document.GetLine(rtf_cursor_y);
+ document.InsertString(line, rtf_cursor_x, rtf_line.ToString());
+ document.FormatText(line, rtf_cursor_x, line, rtf_cursor_x + length, font, rtf_color);
+ }
+
+ if (newline) {
+ rtf_cursor_x = 0;
+ rtf_cursor_y++;
+ } else {
+ rtf_cursor_x += length;
+ }
+ rtf_line.Length = 0; // Empty line
+ }
+ #endregion // Private Methods
+ }
+}