private void CalcSize(IntPtr currentPage, double dpiX, double dpiY, RectangleF printableArea, bool isLandscape, out double width, out double height, out double x, out double y) { x = y = 0; width = Pdfium.FPDF_GetPageWidth(currentPage) / 72 * dpiX; height = Pdfium.FPDF_GetPageHeight(currentPage) / 72 * dpiY; if (_useDP) { return; } //Calculate the size of the printable area in pixels var fitSize = new SizeF( (float)dpiX * printableArea.Width / 100.0f, (float)dpiY * printableArea.Height / 100.0f ); var pageSize = new SizeF( (float)width, (float)height ); var rot = Pdfium.FPDFPage_GetRotation(currentPage); bool isRotated = (rot == PageRotate.Rotate270 || rot == PageRotate.Rotate90) || (width > height); if (AutoRotate && isRotated) { fitSize = new SizeF(fitSize.Height, fitSize.Width); } else if (!AutoRotate && isLandscape) { fitSize = new SizeF(fitSize.Height, fitSize.Width); } switch (PrintSizeMode) { case PrintSizeMode.Fit: var sz = GetRenderSize(pageSize, fitSize); width = sz.Width; height = sz.Height; break; case PrintSizeMode.CustomScale: width *= (double)Scale / 100.0; height *= (double)Scale / 100.0; break; case PrintSizeMode.ActualSize: default: break; } if (AutoCenter) { x = (fitSize.Width - width) / 2; y = (fitSize.Height - height) / 2; } }
/// <summary> /// Raises the System.Drawing.Printing.PrintDocument.QueryPageSettings event. It /// is called immediately before each System.Drawing.Printing.PrintDocument.PrintPage event. /// </summary> /// <param name="e">A System.Drawing.Printing.QueryPageSettingsEventArgs that contains the event data.</param> protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e) { if (AutoRotate) { IntPtr currentPage = Pdfium.FPDF_StartLoadPage(_docForPrint, _pageForPrint); if (currentPage == IntPtr.Zero) { e.Cancel = true; return; } double width = Pdfium.FPDF_GetPageWidth(currentPage); double height = Pdfium.FPDF_GetPageHeight(currentPage); var rotation = Pdfium.FPDFPage_GetRotation(currentPage); bool isRotated = (/*rotation == PageRotate.Rotate270 || rotation == PageRotate.Rotate90 ||*/ width > height); e.PageSettings.Landscape = isRotated; if (currentPage != IntPtr.Zero) { Pdfium.FPDF_ClosePage(currentPage); } } base.OnQueryPageSettings(e); }
/// <summary> /// Raises the System.Drawing.Printing.PrintDocument.PrintPage event. It is called /// before a page prints. /// </summary> /// <param name="e"> A System.Drawing.Printing.PrintPageEventArgs that contains the event data.</param> /// <seealso href="https://pdfium.patagames.com/c-pdf-library/">C# Print PDF</seealso> protected override void OnPrintPage(PrintPageEventArgs e) { base.OnPrintPage(e); if (_pdfDoc == null) { throw new ArgumentNullException("Document"); } IntPtr hdc = IntPtr.Zero; IntPtr currentPage = IntPtr.Zero; try { if (e.Cancel) { return; } currentPage = Pdfium.FPDF_LoadPage(_docForPrint, _pageForPrint); if (currentPage == IntPtr.Zero) { e.Cancel = true; return; } double dpiX = e.Graphics.DpiX; double dpiY = e.Graphics.DpiY; double width = Pdfium.FPDF_GetPageWidth(currentPage) / 72 * dpiX; double height = Pdfium.FPDF_GetPageHeight(currentPage) / 72 * dpiY; double x, y; Rectangle clipRect; CalcSize(dpiX, dpiY, e.PageSettings.PrintableArea, e.MarginBounds, new PointF(e.PageSettings.HardMarginX, e.PageSettings.HardMarginY), e.PageSettings.Landscape, ref width, ref height, out x, out y, out clipRect); int ix = (int)x; int iy = (int)y; int iw = (int)width; int ih = (int)height; using (var page = PdfPage.FromHandle(_pdfDoc, currentPage, _pageForPrint, true)) OnBeforeRenderPage(e.Graphics, page, ref ix, ref iy, ref iw, ref ih, PageRotate.Normal); hdc = e.Graphics.GetHdc(); if (OriginAtMargins) { Pdfium.IntersectClipRect(hdc, clipRect.Left, clipRect.Top, clipRect.Right, clipRect.Bottom); } Pdfium.FPDF_RenderPage(hdc, currentPage, ix, iy, iw, ih, PageRotate.Normal, RenderFlags); if (hdc != IntPtr.Zero) { e.Graphics.ReleaseHdc(hdc); } hdc = IntPtr.Zero; using (var page = PdfPage.FromHandle(_pdfDoc, currentPage, _pageForPrint, true)) OnAfterRenderPage(e.Graphics, page, ix, iy, iw, ih, PageRotate.Normal); //Print next page if (_pageForPrint < PrinterSettings.ToPage - (_useDP ? PrinterSettings.FromPage : 1)) { _pageForPrint++; e.HasMorePages = true; } } finally { if (hdc != IntPtr.Zero) { e.Graphics.ReleaseHdc(hdc); } if (currentPage != IntPtr.Zero) { Pdfium.FPDF_ClosePage(currentPage); } } }