using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.ComponentModel;
namespace ScintillaNet
{
/// <summary>
/// ScintillaNET derived class for handling printing of source code from a Scintilla control.
/// </summary>
[TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
public class PrintDocument : System.Drawing.Printing.PrintDocument
{
private Scintilla m_oScintillaControl;
private int m_iPosition;
private int m_iPrintEnd;
private int m_iCurrentPage;
/// <summary>
/// Default Constructor
/// </summary>
/// <param name="oScintillaControl">Scintilla control being printed</param>
public PrintDocument(Scintilla oScintillaControl)
{
m_oScintillaControl = oScintillaControl;
DefaultPageSettings = new ScintillaNet.PageSettings();
}
internal bool ShouldSerialize()
{
return base.DocumentName != "document" || OriginAtMargins;
}
/// <summary>
/// Method called after the Print method is called and before the first page of the document prints
/// </summary>
/// <param name="e">A PrintPageEventArgs that contains the event data</param>
protected override void OnBeginPrint(PrintEventArgs e)
{
base.OnBeginPrint(e);
m_iPosition = 0;
m_iPrintEnd = m_oScintillaControl.TextLength;
m_iCurrentPage = 1;
}
/// <summary>
/// Method called when the last page of the document has printed
/// </summary>
/// <param name="e">A PrintPageEventArgs that contains the event data</param>
protected override void OnEndPrint(PrintEventArgs e)
{
base.OnEndPrint(e);
}
/// <summary>
/// Method called when printing a page
/// </summary>
/// <param name="e">A PrintPageEventArgs that contains the event data</param>
protected override void OnPrintPage(PrintPageEventArgs e)
{
base.OnPrintPage(e);
PageSettings oPageSettings = null;
HeaderInformation oHeader = ((PageSettings)DefaultPageSettings).Header;
FooterInformation oFooter = ((PageSettings)DefaultPageSettings).Footer;
Rectangle oPrintBounds = e.MarginBounds;
bool bIsPreview = this.PrintController.IsPreview;
// When not in preview mode, adjust graphics to account for hard margin of the printer
if (!bIsPreview)
{
e.Graphics.TranslateTransform(-e.PageSettings.HardMarginX, -e.PageSettings.HardMarginY);
}
// Get the header and footer provided if using Scintilla.Printing.PageSettings
if (e.PageSettings is PageSettings)
{
oPageSettings = (PageSettings)e.PageSettings;
oHeader = oPageSettings.Header;
oFooter = oPageSettings.Footer;
m_oScintillaControl.NativeInterface.SetPrintMagnification(oPageSettings.FontMagnification);
m_oScintillaControl.NativeInterface.SetPrintColourMode((int)oPageSettings.ColorMode);
}
// Draw the header and footer and get remainder of page bounds
oPrintBounds = DrawHeader(e.Graphics, oPrintBounds, oHeader);
oPrintBounds = DrawFooter(e.Graphics, oPrintBounds, oFooter);
// When not in preview mode, adjust page bounds to account for hard margin of the printer
if (!bIsPreview)
{
oPrintBounds.Offset((int)-e.PageSettings.HardMarginX, (int)-e.PageSettings.HardMarginY);
}
DrawCurrentPage(e.Graphics, oPrintBounds);
// Increment the page count and determine if there are more pages to be printed
m_iCurrentPage++;
e.HasMorePages = (m_iPosition < m_iPrintEnd);
}
private Rectangle DrawHeader(Graphics oGraphics, Rectangle oBounds, PageInformation oHeader)
{
if (oHeader.Display)
{
Rectangle oHeaderBounds = new Rectangle(oBounds.Left, oBounds.Top, oBounds.Width, oHeader.Height);
oHeader.Draw(oGraphics, oHeaderBounds, this.DocumentName, m_iCurrentPage);
return new Rectangle(
oBounds.Left, oBounds.Top + oHeaderBounds.Height + oHeader.Margin,
oBounds.Width, oBounds.Height - oHeaderBounds.Height - oHeader.Margin
);
}
else
{
return oBounds;
}
}
private Rectangle DrawFooter(Graphics oGraphics, Rectangle oBounds, PageInformation oFooter)
{
if (oFooter.Display)
{
int iHeight = oFooter.Height;
Rectangle oFooterBounds = new Rectangle(oBounds.Left, oBounds.Bottom - iHeight, oBounds.Width, iHeight);
oFooter.Draw(oGraphics, oFooterBounds, this.DocumentName, m_iCurrentPage);
return new Rectangle(
oBounds.Left, oBounds.Top,
oBounds.Width, oBounds.Height - oFooterBounds.Height - oFooter.Margin
);
}
else
{
return oBounds;
}
}
private void DrawCurrentPage(Graphics oGraphics, Rectangle oBounds)
{
Point[] oPoints = {
new Point(oBounds.Left, oBounds.Top),
new Point(oBounds.Right, oBounds.Bottom)
};
oGraphics.TransformPoints(CoordinateSpace.Device, CoordinateSpace.Page, oPoints);
PrintRectangle oPrintRectangle = new PrintRectangle(oPoints[0].X, oPoints[0].Y, oPoints[1].X, oPoints[1].Y);
RangeToFormat oRangeToFormat = new RangeToFormat();
oRangeToFormat.hdc = oRangeToFormat.hdcTarget = oGraphics.GetHdc();
oRangeToFormat.rc = oRangeToFormat.rcPage = oPrintRectangle;
oRangeToFormat.chrg.cpMin = m_iPosition;
oRangeToFormat.chrg.cpMax = m_iPrintEnd;
m_iPosition = m_oScintillaControl.NativeInterface.FormatRange(true, ref oRangeToFormat);
}
public new string DocumentName
{
get
{
return base.DocumentName;
}
set
{
base.DocumentName = value;
}
}
private bool ShouldSerializeDocumentName()
{
return DocumentName != "document";
}
private void ResetDocumentName()
{
DocumentName = "document";
}
public new bool OriginAtMargins
{
get
{
return base.OriginAtMargins;
}
set
{
base.OriginAtMargins = value;
}
}
private bool ShouldSerializeOriginAtMargins()
{
return OriginAtMargins;
}
private void ResetOriginAtMargins()
{
OriginAtMargins = false;
}
}
}