using ComPDFKit.Controls.Printer; using ComPDFKit.Import; using ComPDFKit.PDFPage; using ComPDFKit.Tool.Help; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Xml.Linq; using static System.Windows.Forms.AxHost; using Color = System.Drawing.Color; using Pen = System.Drawing.Pen; using Point = System.Drawing.Point; using Rectangle = System.Drawing.Rectangle; namespace ComPDFKit.Controls.PDFControl { /// /// Interaction logic for PrintPreviewControl.xaml /// public partial class PrintPreviewControl : UserControl, INotifyPropertyChanged { private double PDFToMediaDpiRatio = 100.0 / 72.0; private double mmToDpiRatio = 100 / 25.4; private PrintSettingsInfo printSettingsInfo; private Bitmap blankPageBitmap; private int originalPaperIndex; private string _paperIndex = "1"; public string PaperIndex { get { return _paperIndex; } set { if (int.TryParse(value, out int paperIndex)) { if (paperIndex > 0 && paperIndex <= TargetPaperList.Count) { originalPaperIndex = paperIndex; if (UpdateProper(ref _paperIndex, value)) { TargetPaperIndex = paperIndex - 1; } } else { OnPropertyChanged(); } } else if (value == string.Empty) { _paperIndex = value; } } } private int _printedPageCount; public int PrintedPageCount { get => _printedPageCount; set => UpdateProper(ref _printedPageCount, value); } private string _paperType; public string PaperKind { get => _paperType; set => UpdateProper(ref _paperType, value); } private string _paperWidth; public string PaperWidth { get => _paperWidth; set => UpdateProper(ref _paperWidth, value); } private string _paperHeight; public string PaperHeight { get => _paperHeight; set => UpdateProper(ref _paperHeight, value); } private string _viewBoxWidth = "0"; public string ViewBoxWidth { get => _viewBoxWidth; set => UpdateProper(ref _viewBoxWidth, value); } private string _viewBoxHeight = "0"; public string ViewBoxHeight { get => _viewBoxHeight; set => UpdateProper(ref _viewBoxHeight, value); } private BitmapSource _priviewBitmapSource; public BitmapSource PreviewBitmapSource { get => _priviewBitmapSource; set => UpdateProper(ref _priviewBitmapSource, value); } public List TargetPaperList = new List(); private int _targetPaperIndex = 0; public int TargetPaperIndex { get => _targetPaperIndex; set { if (UpdateProper(ref _targetPaperIndex, value)) { JumpToSelectedPage(); } } } public void SetViewBox(double height, double width) { if (height / width >= (248.0 / 180.0)) { ViewBoxHeight = "248.0"; ViewBoxWidth = (width / height * 248.0).ToString(); } else { ViewBoxWidth = "180.0"; ViewBoxHeight = (height / width * 180.0).ToString(); } } private void SetPreviewBox() { PaperKind = printSettingsInfo.PaperSize.Kind.ToString(); if (printSettingsInfo.PrintOrientation == PrintOrientation.Portrait) { PaperWidth = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Width)); PaperHeight = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Height)); } else { PaperWidth = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Height)); PaperHeight = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Width)); } if (!(printSettingsInfo.PrintMode is PosterModeInfo)) { SetViewBox(double.Parse(PaperHeight), double.Parse(PaperWidth)); } } internal void Init(PrintSettingsInfo printSettingsInfo, bool needPageReset = false) { this.printSettingsInfo = printSettingsInfo; PrintedPageCount = PrintHelper.CaculatePrintedPageCount(printSettingsInfo); CalculatePaperCollection(needPageReset); SetPreviewBox(); PaintPageByCurrentPreviewIndex(); } private void CreateBlankBitmap() { int width = printSettingsInfo.PrintOrientation == PrintOrientation.Portrait ? printSettingsInfo.PaperSize.Width : printSettingsInfo.PaperSize.Height; int height = printSettingsInfo.PrintOrientation == PrintOrientation.Portrait ? printSettingsInfo.PaperSize.Height : printSettingsInfo.PaperSize.Width; blankPageBitmap = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(blankPageBitmap)) { g.Clear(Color.White); } } public void CalculatePaperCollection(bool needPageReset = false) { TargetPaperList = new List(printSettingsInfo.PageRangeList); if (printSettingsInfo.IsReverseOrder) { TargetPaperList.Reverse(); } if (needPageReset) { PaperIndex = "1"; } } public PrintPreviewControl() { InitializeComponent(); DataContext = this; } private readonly object lockObject = new object(); private void PaintPageByCurrentPreviewIndex() { CreateBlankBitmap(); SetPreviewBox(); lock (lockObject) { PreviewPageBySizeMode(TargetPaperList[TargetPaperIndex]); } } [System.Runtime.InteropServices.DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); public BitmapSource ToBitmapSource(System.Drawing.Bitmap bmp) { IntPtr ptr = bmp.GetHbitmap();//obtain the Hbitmap try { BitmapSource bmpsrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap ( ptr, IntPtr.Zero, new Int32Rect(0, 0, bmp.Width, bmp.Height), System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() ); return bmpsrc; } finally { DeleteObject(ptr); } } public Bitmap Resize(Bitmap input, int targetWidth, int targetHeight) { try { var actualBitmap = new Bitmap(targetWidth, targetHeight); var g = Graphics.FromImage(actualBitmap); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(input, new Rectangle(0, 0, targetWidth, targetHeight), new Rectangle(0, 0, input.Width, input.Height), GraphicsUnit.Pixel); g.Dispose(); return actualBitmap; } catch (Exception ex) { return null; } } private void PreviewPageBySizeMode(int index) { if (!(printSettingsInfo.PrintMode is SizeModeInfo sizeModeInfo)) { return; } Bitmap printBitmap = new Bitmap((int)double.Parse(PaperWidth), (int)double.Parse(PaperHeight)); CPDFPage page = printSettingsInfo.Document.PageAtIndex(index); CSize cSize = page.PageSize; System.Drawing.Size pageSize = new System.Drawing.Size((int)cSize.width, (int)cSize.height); CRect pageRect = new CRect(0, (int)(pageSize.Height), (int)(pageSize.Width), 0); byte[] bmpData = new byte[(int)(pageRect.width() * pageRect.height() * 4)]; if (page != null) { page.RenderPageBitmapWithMatrix((float)1, pageRect, 0xFFFFFFFF, bmpData, printSettingsInfo.IsPrintAnnot?1:0, printSettingsInfo.IsPrintForm); Point startPoint = new Point(0, 0); Bitmap bitmap = PrintHelper.BuildBmp((int)pageRect.width(), (int)pageRect.height(), bmpData); if (printSettingsInfo.IsGrayscale) { bitmap = PrintHelper.ToGray(bitmap, 0); } if (sizeModeInfo.SizeType == SizeType.Adaptive) { int resizedHeight = 0; int resizedWidth = 0; if (bitmap.Height / bitmap.Width >= (float.Parse(PaperHeight) / float.Parse(PaperWidth))) { resizedHeight = (int)(float.Parse(PaperHeight)); resizedWidth = (int)((float.Parse(PaperHeight) / bitmap.Height * bitmap.Width)); } else { resizedWidth = (int)(float.Parse(PaperWidth)); resizedHeight = (int)((float.Parse(PaperWidth) / bitmap.Width * bitmap.Height)); } bitmap = Resize(bitmap, resizedWidth, resizedHeight); startPoint.X = (blankPageBitmap.Width - resizedWidth) / 2; startPoint.Y = (blankPageBitmap.Height - resizedHeight) / 2; printBitmap = PrintHelper.CombineBitmap(blankPageBitmap, bitmap, startPoint); } else if (sizeModeInfo.SizeType == SizeType.Actural) { bitmap = PrintHelper.ResizeBitmap(bitmap, 100); startPoint.X = (blankPageBitmap.Width - bitmap.Width) / 2; startPoint.Y = (blankPageBitmap.Height - bitmap.Height) / 2; printBitmap = PrintHelper.CombineBitmap(blankPageBitmap, bitmap, startPoint); } else { // 按比例缩小bitmap float scale = sizeModeInfo.SizeType == SizeType.Customized ? sizeModeInfo.Scale : 1; bitmap = PrintHelper.ResizeBitmap(bitmap, scale); startPoint.X = (blankPageBitmap.Width - bitmap.Width) / 2; startPoint.Y = (blankPageBitmap.Height - bitmap.Height) / 2; printBitmap = PrintHelper.CombineBitmap(blankPageBitmap, bitmap, startPoint); } } PreviewBitmapSource = ToBitmapSource(printBitmap); } public void JumpToSelectedPage() { PaintPageByCurrentPreviewIndex(); } public event PropertyChangedEventHandler PropertyChanged; protected bool UpdateProper(ref T properValue, T newValue, [CallerMemberName] string properName = "") { if (object.Equals(properValue, newValue)) return false; properValue = newValue; OnPropertyChanged(properName); return true; } protected void OnPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); private void btnPreButton_Click(object sender, RoutedEventArgs e) { if (!int.TryParse(PaperIndex, out int _)) { _paperIndex = originalPaperIndex.ToString(); } PaperIndex = (int.Parse(PaperIndex) - 1).ToString(); } private void btnNextButton_Click(object sender, RoutedEventArgs e) { if (!int.TryParse(PaperIndex, out int _)) { _paperIndex = originalPaperIndex.ToString(); } PaperIndex = (int.Parse(PaperIndex) + 1).ToString(); } private void txbPageIndex_LostFocus(object sender, RoutedEventArgs e) { if(PaperIndex == string.Empty) { PaperIndex = (originalPaperIndex).ToString(); } } private void txbPageIndex_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { if (e.NewFocus is Button button && (button == btnNextButton||button == btnPreButton)) { e.Handled = true; } } } }