103 lines
4.0 KiB
C#
103 lines
4.0 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Drawing.Printing;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Elwig.Helpers.Printing {
|
|
public class PdfPrintDocument : PrintDocument {
|
|
|
|
private readonly IntPtr _handle;
|
|
private readonly int _pageCount;
|
|
private readonly double _dpi;
|
|
|
|
private int _currentPage;
|
|
|
|
public PdfPrintDocument(string path, string? password = null, double dpi = 300.0) :
|
|
base() {
|
|
_handle = PdfiumNative.FPDF_LoadDocument(path, password);
|
|
_pageCount = PdfiumNative.FPDF_GetPageCount(_handle);
|
|
_dpi = dpi;
|
|
}
|
|
|
|
protected override void Dispose(bool disposing) {
|
|
PdfiumNative.FPDF_CloseDocument(_handle);
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
protected override void OnBeginPrint(PrintEventArgs evt) {
|
|
_currentPage = (PrinterSettings.FromPage != 0) ? (PrinterSettings.FromPage - 1) : 0;
|
|
base.OnBeginPrint(evt);
|
|
}
|
|
|
|
protected override void OnPrintPage(PrintPageEventArgs evt) {
|
|
if (_currentPage < _pageCount) {
|
|
IntPtr page = PdfiumNative.FPDF_LoadPage(_handle, _currentPage);
|
|
double width = PdfiumNative.FPDF_GetPageWidth(page);
|
|
double height = PdfiumNative.FPDF_GetPageHeight(page);
|
|
int pixelWidth = (int)(width / 72.0 * _dpi);
|
|
int pixelHeight = (int)(height / 72.0 * _dpi);
|
|
|
|
IntPtr bitmap = PdfiumNative.FPDFBitmap_Create(pixelWidth, pixelHeight, 1);
|
|
PdfiumNative.FPDF_RenderPageBitmap(bitmap, page, 0, 0, pixelWidth, pixelHeight, 0, 0);
|
|
|
|
IntPtr buffer = PdfiumNative.FPDFBitmap_GetBuffer(bitmap);
|
|
int stride = PdfiumNative.FPDFBitmap_GetStride(bitmap);
|
|
using (var bmp = new Bitmap(pixelWidth, pixelHeight, stride, PixelFormat.Format32bppArgb, buffer)) {
|
|
evt.Graphics?.DrawImage(bmp, evt.PageBounds);
|
|
}
|
|
_currentPage++;
|
|
|
|
PdfiumNative.FPDFBitmap_Destroy(bitmap);
|
|
PdfiumNative.FPDF_ClosePage(page);
|
|
}
|
|
evt.HasMorePages = _currentPage < ((PrinterSettings.ToPage == 0) ? _pageCount : Math.Min(PrinterSettings.ToPage, _pageCount));
|
|
base.OnPrintPage(evt);
|
|
}
|
|
}
|
|
|
|
internal partial class PdfiumNative {
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial void FPDF_InitLibrary();
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial void FPDF_DestroyLibrary();
|
|
|
|
[LibraryImport("pdfium.dll", StringMarshalling = StringMarshalling.Utf8)]
|
|
public static partial IntPtr FPDF_LoadDocument(string filePath, string? password);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial void FPDF_CloseDocument(IntPtr document);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial int FPDF_GetPageCount(IntPtr document);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial IntPtr FPDF_LoadPage(IntPtr document, int pageIndex);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial void FPDF_ClosePage(IntPtr page);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial double FPDF_GetPageWidth(IntPtr page);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial double FPDF_GetPageHeight(IntPtr page);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial IntPtr FPDFBitmap_Create(int width, int height, int alpha);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial void FPDFBitmap_Destroy(IntPtr bitmap);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial IntPtr FPDFBitmap_GetBuffer(IntPtr bitmap);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial int FPDFBitmap_GetStride(IntPtr bitmap);
|
|
|
|
[LibraryImport("pdfium.dll")]
|
|
public static partial void FPDF_RenderPageBitmap(IntPtr bitmap, IntPtr page, int start_x, int start_y, int size_x, int size_y, int rotate, int flags);
|
|
}
|
|
}
|