using System;
|
using System.Drawing.Printing;
|
using System.Windows.Forms;
|
|
namespace PdfGold.Renderer
|
{
|
/// <summary>
|
/// Implements printing of pages from a PDF document.
|
/// </summary>
|
public partial class PdfRenderer
|
{
|
// Invoking print dialog with UseEXDialog set from a toolstrip button
|
// has a known issue that the PrintDialog does not get the focus. This
|
// forces the user to click the Print or Cancel buttons twice. The
|
// following delegate is used to solve this problem by performing the
|
// operation asynchronously and allowing the .NET events to complete
|
// before the print dialog is displayed.
|
private delegate void PrintDocumentDelegate();
|
|
/// <summary>
|
/// Print the current document.
|
/// </summary>
|
public void PrintDocument()
|
{
|
BeginInvoke(new PrintDocumentDelegate(() =>
|
{
|
using (var form = new PrintDialog())
|
using (var pdf = new PdfPrintDocument(PdfDocument, PageNumber, Rotation))
|
{
|
form.AllowSomePages = PageCount > 1;
|
form.AllowCurrentPage = PageCount > 1;
|
form.Document = pdf;
|
form.UseEXDialog = true;
|
|
if (form.ShowDialog(this) == DialogResult.OK)
|
{
|
if (pdf.PrinterSettings.FromPage <= PageCount)
|
{
|
pdf.Print();
|
}
|
}
|
}
|
}));
|
}
|
|
private class PdfPrintDocument : PrintDocument
|
{
|
#region Instance Variables
|
|
public PdfDocument document;
|
private int pageNumber;
|
private readonly int currentPage;
|
private readonly PageRotation rotation;
|
|
#endregion
|
|
#region Properties
|
|
/// <summary>
|
/// If 'true', scale the image to fit the paper.
|
/// </summary>
|
public bool FitToPage { get; set; }
|
|
/// <summary>
|
/// If 'true', center the page on the paper.
|
/// </summary>
|
public bool CenterInPage { get; set; }
|
|
/// <summary>
|
/// If 'true', automatically determine portrait or landscape mode.
|
/// </summary>
|
public bool AutoOrient { get; set; }
|
|
#endregion
|
|
#region Constructor
|
|
public PdfPrintDocument(PdfDocument document, int currentPage, PageRotation rotation)
|
{
|
this.document = new PdfDocument(document);
|
this.currentPage = currentPage;
|
this.rotation = rotation;
|
|
PrinterSettings.FromPage = PrinterSettings.MinimumPage = 1;
|
PrinterSettings.ToPage = PrinterSettings.MaximumPage = document.PageCount;
|
|
FitToPage = true;
|
}
|
|
#endregion
|
|
#region Overrides
|
|
protected override void OnBeginPrint(PrintEventArgs e)
|
{
|
if (PrinterSettings.PrintRange == PrintRange.CurrentPage)
|
PrinterSettings.FromPage = PrinterSettings.ToPage = currentPage + 1;
|
pageNumber = PrinterSettings.FromPage - 1;
|
}
|
|
protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
|
{
|
e.PageSettings.Landscape = PrinterSettings.DefaultPageSettings.Landscape || rotation == PageRotation.Degrees90 || rotation == PageRotation.Degrees270;
|
}
|
|
protected override void OnPrintPage(PrintPageEventArgs e)
|
{
|
if (pageNumber < document.PageCount)
|
{
|
var page = document.Pages[pageNumber];
|
if (document.Form != null)
|
{
|
page.Flatten(FlattenMode.Print);
|
page.Unload();
|
}
|
|
var rcPrint = new PdfRectangle(e.PageBounds.Left * e.Graphics.DpiX / 100, e.PageBounds.Top * e.Graphics.DpiX / 100, e.PageBounds.Right * e.Graphics.DpiX / 100, e.PageBounds.Bottom * e.Graphics.DpiX / 100);
|
var rcDisplay = new PdfRectangle(rcPrint);
|
|
if (FitToPage)
|
{
|
var rcPage = page.Bounds;
|
var zoom = Math.Min(rcPrint.Width / rcPage.Width, rcPrint.Height / rcPage.Height);
|
rcDisplay.Width = rcPage.Width * zoom;
|
rcDisplay.Height = rcPage.Height * zoom;
|
}
|
|
if (CenterInPage)
|
{
|
rcDisplay.Left += (rcPrint.Width - rcDisplay.Width) / 2;
|
rcDisplay.Top += (rcPrint.Height - rcDisplay.Height) / 2;
|
}
|
|
var options = RenderOptions.Annotations | RenderOptions.Printing;
|
if (!e.PageSettings.Color)
|
options |= RenderOptions.GrayScale;
|
|
page.Render(e.Graphics, rcDisplay.Rectangle, rotation, options);
|
}
|
|
e.HasMorePages = ++pageNumber < PrinterSettings.ToPage;
|
}
|
|
protected override void Dispose(bool disposing)
|
{
|
if (document != null)
|
{
|
document.Dispose();
|
document = null;
|
}
|
base.Dispose(disposing);
|
}
|
#endregion
|
}
|
}
|
}
|