198 lines
8.2 KiB
C#
198 lines
8.2 KiB
C#
|
#region MigraDoc - Creating Documents on the Fly
|
||
|
//
|
||
|
// Authors:
|
||
|
// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
|
||
|
//
|
||
|
// Copyright (c) 2001-2013 empira Software GmbH, Cologne Area (Germany)
|
||
|
//
|
||
|
// http://www.pdfsharp.com
|
||
|
// http://www.migradoc.com
|
||
|
// http://sourceforge.net/projects/pdfsharp
|
||
|
//
|
||
|
// 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.
|
||
|
#endregion
|
||
|
|
||
|
using System;
|
||
|
using System.Diagnostics;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Drawing;
|
||
|
using System.Drawing.Printing;
|
||
|
using PdfSharp;
|
||
|
using PdfSharp.Drawing;
|
||
|
using MigraDoc.DocumentObjectModel.publics;
|
||
|
using MigraDoc.DocumentObjectModel.Visitors;
|
||
|
using MigraDoc.DocumentObjectModel.IO;
|
||
|
|
||
|
namespace MigraDoc.Rendering.Printing
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Represents a specialized System.Drawing.Printing.PrintDocument for MigraDoc documents.
|
||
|
/// This component knows about MigraDoc and simplifies printing of MigraDoc documents.
|
||
|
/// </summary>
|
||
|
public class MigraDocPrintDocument : PrintDocument
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Initializes a new instance of the <see cref="T:MigraDoc.Rendering.Printing.MigraDocPrintDocument"/> class.
|
||
|
/// </summary>
|
||
|
public MigraDocPrintDocument()
|
||
|
{
|
||
|
DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
|
||
|
OriginAtMargins = false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Initializes a new instance of the <see cref="T:MigraDoc.Rendering.Printing.MigraDocPrintDocument"/> class
|
||
|
/// with the specified <see cref="T:MigraDoc.Rendering.DocumentRenderer"/> object.
|
||
|
/// </summary>
|
||
|
public MigraDocPrintDocument(DocumentRenderer renderer)
|
||
|
{
|
||
|
_renderer = renderer;
|
||
|
DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
|
||
|
OriginAtMargins = false;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets the DocumentRenderer that prints the pages of the document.
|
||
|
/// </summary>
|
||
|
public DocumentRenderer Renderer
|
||
|
{
|
||
|
get { return _renderer; }
|
||
|
set { _renderer = value; }
|
||
|
}
|
||
|
DocumentRenderer _renderer;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets or sets the page number that identifies the selected page. It it used on printing when
|
||
|
/// PrintRange.Selection is set.
|
||
|
/// </summary>
|
||
|
public int SelectedPage
|
||
|
{
|
||
|
get { return _selectedPage; }
|
||
|
set { _selectedPage = value; }
|
||
|
}
|
||
|
int _selectedPage;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.BeginPrint"/> event. It is called after the <see cref="M:System.Drawing.Printing.PrintDocument.Print"/> method is called and before the first page of the document prints.
|
||
|
/// </summary>
|
||
|
/// <param name="e">A <see cref="T:System.Drawing.Printing.PrintEventArgs"/> that contains the event data.</param>
|
||
|
protected override void OnBeginPrint(PrintEventArgs e)
|
||
|
{
|
||
|
Debug.Assert(_renderer != null, "Cannot print without a MigraDoc.Rendering.DocumentRenderer.");
|
||
|
|
||
|
base.OnBeginPrint(e);
|
||
|
if (!e.Cancel)
|
||
|
{
|
||
|
switch (PrinterSettings.PrintRange)
|
||
|
{
|
||
|
case PrintRange.AllPages:
|
||
|
_pageNumber = 1;
|
||
|
_pageCount = _renderer.FormattedDocument.PageCount;
|
||
|
break;
|
||
|
|
||
|
case PrintRange.SomePages:
|
||
|
_pageNumber = PrinterSettings.FromPage;
|
||
|
_pageCount = PrinterSettings.ToPage - PrinterSettings.FromPage + 1;
|
||
|
break;
|
||
|
|
||
|
case PrintRange.Selection:
|
||
|
_pageNumber = _selectedPage;
|
||
|
_pageCount = 1;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Debug.Assert(false, "Invalid PrinterRange.");
|
||
|
e.Cancel = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
int _pageNumber = -1;
|
||
|
int _pageCount;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.QueryPageSettings"/> event. It is called immediately before each <see cref="E:System.Drawing.Printing.PrintDocument.PrintPage"/> event.
|
||
|
/// </summary>
|
||
|
/// <param name="e">A <see cref="T:System.Drawing.Printing.QueryPageSettingsEventArgs"/> that contains the event data.</param>
|
||
|
protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
|
||
|
{
|
||
|
base.OnQueryPageSettings(e);
|
||
|
if (!e.Cancel)
|
||
|
{
|
||
|
PageSettings settings = e.PageSettings;
|
||
|
PageInfo pageInfo = _renderer.FormattedDocument.GetPageInfo(_pageNumber);
|
||
|
|
||
|
// set portrait/landscape
|
||
|
settings.Landscape = pageInfo.Orientation == PageOrientation.Landscape;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.PrintPage"/> event. It is called before a page prints.
|
||
|
/// </summary>
|
||
|
/// <param name="e">A <see cref="T:System.Drawing.Printing.PrintPageEventArgs"/> that contains the event data.</param>
|
||
|
protected override void OnPrintPage(PrintPageEventArgs e)
|
||
|
{
|
||
|
base.OnPrintPage(e);
|
||
|
if (!e.Cancel)
|
||
|
{
|
||
|
PageSettings settings = e.PageSettings;
|
||
|
try
|
||
|
{
|
||
|
Graphics graphics = e.Graphics;
|
||
|
IntPtr hdc = graphics.GetHdc();
|
||
|
int xOffset = GetDeviceCaps(hdc, PHYSICALOFFSETX);
|
||
|
int yOffset = GetDeviceCaps(hdc, PHYSICALOFFSETY);
|
||
|
graphics.ReleaseHdc(hdc);
|
||
|
graphics.TranslateTransform(-xOffset * 100 / graphics.DpiX, -yOffset * 100 / graphics.DpiY);
|
||
|
// Recall: Width and Height are exchanged when settings.Landscape is true.
|
||
|
XSize size = new XSize(e.PageSettings.Bounds.Width / 100.0 * 72, e.PageSettings.Bounds.Height / 100.0 * 72);
|
||
|
const float scale = 100f / 72f;
|
||
|
graphics.ScaleTransform(scale, scale);
|
||
|
// draw line A4 portrait
|
||
|
//graphics.DrawLine(Pens.Red, 0, 0, 21f / 2.54f * 72, 29.7f / 2.54f * 72);
|
||
|
|
||
|
}
|
||
|
catch
|
||
|
{
|
||
|
e.Cancel = true;
|
||
|
}
|
||
|
_pageNumber++;
|
||
|
_pageCount--;
|
||
|
e.HasMorePages = _pageCount > 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.EndPrint"/> event. It is called when the last page of the document has printed.
|
||
|
/// </summary>
|
||
|
/// <param name="e">A <see cref="T:System.Drawing.Printing.PrintEventArgs"/> that contains the event data.</param>
|
||
|
protected override void OnEndPrint(PrintEventArgs e)
|
||
|
{
|
||
|
base.OnEndPrint(e);
|
||
|
_pageNumber = -1;
|
||
|
}
|
||
|
|
||
|
[DllImport("gdi32.dll")]
|
||
|
static extern int GetDeviceCaps(IntPtr hdc, int capability);
|
||
|
const int PHYSICALOFFSETX = 112; // Physical Printable Area x margin
|
||
|
const int PHYSICALOFFSETY = 113; // Physical Printable Area y margin
|
||
|
}
|
||
|
}
|