#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 { /// /// Represents a specialized System.Drawing.Printing.PrintDocument for MigraDoc documents. /// This component knows about MigraDoc and simplifies printing of MigraDoc documents. /// public class MigraDocPrintDocument : PrintDocument { /// /// Initializes a new instance of the class. /// public MigraDocPrintDocument() { DefaultPageSettings.Margins = new Margins(0, 0, 0, 0); OriginAtMargins = false; } /// /// Initializes a new instance of the class /// with the specified object. /// public MigraDocPrintDocument(DocumentRenderer renderer) { _renderer = renderer; DefaultPageSettings.Margins = new Margins(0, 0, 0, 0); OriginAtMargins = false; } /// /// Gets or sets the DocumentRenderer that prints the pages of the document. /// public DocumentRenderer Renderer { get { return _renderer; } set { _renderer = value; } } DocumentRenderer _renderer; /// /// Gets or sets the page number that identifies the selected page. It it used on printing when /// PrintRange.Selection is set. /// public int SelectedPage { get { return _selectedPage; } set { _selectedPage = value; } } int _selectedPage; /// /// Raises the event. It is called after the method is called and before the first page of the document prints. /// /// A that contains the event data. 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; /// /// Raises the event. It is called immediately before each event. /// /// A that contains the event data. 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; } } /// /// Raises the event. It is called before a page prints. /// /// A that contains the event data. 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; } } /// /// Raises the event. It is called when the last page of the document has printed. /// /// A that contains the event data. 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 } }