Click here to Skip to main content
15,887,175 members
Articles / Desktop Programming / Windows Forms

Storm - the world's best IDE framework for .NET

Rate me:
Please Sign up or sign in to vote.
4.96/5 (82 votes)
4 Feb 2010LGPL311 min read 274.9K   6.5K   340  
Create fast, flexible, and extensible IDE applications easily with Storm - it takes nearly no code at all!
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Printing;

using Storm.TextEditor.Parser.Objects;
using Storm.TextEditor.Parser.Objects.Collections;

namespace Storm.TextEditor.Editor.Printing
{
	/// <summary>
	/// Defines a reusable object that sends output to a printer, when printing from a SyntaxDocument.
	/// </summary>
	[ToolboxItem(true)]
	public class CodePrintDocument
		: PrintDocument
	{
		#region Fields

		private Font fontNormal = null;
		private Font fontBreak  = null;
		private int  rowIndex   = 0;

		private SyntaxDocument document      = null;
		private RowCollection  rowCollection = null;

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the document that the CodePrintDocument should print.
		/// </summary>
		public SyntaxDocument Document
		{
			get { return document; }
			set { document = value; }
		}

		#endregion

		#region Methods

		#region Protected

		/// <summary>
		/// Override OnBeginPaint to re-initialize fields of the CodePrintDocument when it is about to print.
		/// </summary>
		/// <param name="ev">PrintEventArgs.</param>
		protected override void OnBeginPrint(PrintEventArgs ev)
		{
			fontNormal = new Font("Courier new", 8, FontStyle.Regular);
			fontBreak  = new Font("Courier New", 8, FontStyle.Bold);
			rowIndex   = 0;

			base.OnBeginPrint(ev);
		}

		/// <summary>
		/// Override OnPrintPage to execute logic for printing a SyntaxDocument.
		/// </summary>
		/// <param name="ev">PrintPageEventArgs.</param>
		protected override void OnPrintPage(PrintPageEventArgs ev)
		{
			float maximumHeight = 0;
			int   currentIndex  = 0;

			float leftMargin  = ev.MarginBounds.Left;
			float rightMargin = ev.MarginBounds.Right;
			float topMargin   = ev.MarginBounds.Top;

			float y = 0;

			if (rowCollection == null)
			{
				Document.ParseAll();
				Document.ParseAll(true);

				rowCollection = new RowCollection();
				foreach (Row row in this.Document)
				{
					bool  rowBreak = false;
					float x        = leftMargin;

					Row newRow = new Row();
					rowCollection.Add(newRow);

					foreach (Word word in row)
					{
						Font font = fontNormal;
						if (word.Style != null)
						{
							FontStyle fontStyle = 0;

							if (word.Style.Bold == true)
								fontStyle |= FontStyle.Bold;

							if (word.Style.Italic == true)
								fontStyle |= FontStyle.Italic;

							if (word.Style.Underline == true)
								fontStyle |= FontStyle.Underline;

							font = new Font("Courier new", 8, fontStyle);
						}

						SizeF wordSize = ev.Graphics.MeasureString(word.Text, font);
						if (x + wordSize.Width > rightMargin)
						{
							Word breakWord      = new Word();
							char breakCharacter = (char)0xbf;
							breakWord.Text = breakCharacter + "";

							newRow.Add(breakWord);
							rowBreak = true;

							newRow = new Row();
							rowCollection.Add(newRow);
							x = leftMargin;
						}

						x += wordSize.Width;
						newRow.Add(word);
					}

					if (rowBreak == true)
						rowCollection.Add(new Row());
				}
			}

			maximumHeight = ev.MarginBounds.Height / fontNormal.GetHeight(ev.Graphics);
			while (currentIndex < maximumHeight && (rowIndex < rowCollection.Count))
			{
				float x = leftMargin;
				y     = topMargin + (currentIndex * fontNormal.GetHeight(ev.Graphics));

				Row row = rowCollection[rowIndex];
				foreach (Word word in row)
				{
					if (word.Text == ((char)0xbf) + "")	// Word is a break word.
						ev.Graphics.DrawString(word.Text, fontBreak, Brushes.Black, x, y, new StringFormat());
					else
					{
						SizeF wordSize = ev.Graphics.MeasureString(word.Text, fontNormal);
						if (word.Text != null && (".,:;".IndexOf(word.Text) >= 0))
						{
							wordSize.Width = 6;
							x -= 4;
						}

						if (word.Text == "\t")
							wordSize.Width = ev.Graphics.MeasureString("...", fontNormal).Width;

						Color foreColor = Color.Black;
						Font  font      = fontNormal;

						if (word.Style != null)
						{
							foreColor           = word.Style.ForeColor;
							FontStyle fontStyle = 0;

							if (word.Style.Bold == true)
								fontStyle |= FontStyle.Bold;

							if (word.Style.Italic == true)
								fontStyle |= FontStyle.Italic;

							if (word.Style.Underline == true)
								fontStyle |= FontStyle.Underline;

							font = new Font("Courier new", 8, fontStyle);

							if (word.Style.Transparent == false)
							{
								Color backColor = word.Style.BackColor;
								ev.Graphics.FillRectangle(new SolidBrush(backColor), x, y, wordSize.Width, fontNormal.GetHeight(ev.Graphics));
							}
						}

						foreColor = Color.FromArgb(foreColor.R, foreColor.G, foreColor.B);	// Refresh.
						ev.Graphics.DrawString(word.Text, font, new SolidBrush(foreColor), x, y, new StringFormat());
						x += wordSize.Width;
					}
				}

				currentIndex++;
				rowIndex++;
			}

			if (rowIndex < rowCollection.Count)
				ev.HasMorePages = true;
			else
				ev.HasMorePages = false;

			base.OnPrintPage(ev);
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of CodePrintDocument.
		/// </summary>
		public CodePrintDocument()
			: base()
		{
		}

		/// <summary>
		/// Initializes a new instance of CodePrintDocument.
		/// </summary>
		public CodePrintDocument(SyntaxDocument document)
			: base()
		{
			this.Document = document;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)



Comments and Discussions