PrintPreviewControl.xaml.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. using ComPDFKit.Controls.Printer;
  2. using ComPDFKit.Import;
  3. using ComPDFKit.PDFAnnotation;
  4. using ComPDFKit.PDFPage;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.ComponentModel;
  8. using System.Drawing;
  9. using System.Printing;
  10. using System.Runtime.CompilerServices;
  11. using System.Windows;
  12. using System.Windows.Controls;
  13. using System.Windows.Input;
  14. using System.Windows.Media;
  15. using System.Windows.Media.Imaging;
  16. using Color = System.Drawing.Color;
  17. using Point = System.Drawing.Point;
  18. using Rectangle = System.Drawing.Rectangle;
  19. namespace ComPDFKit.Controls.PDFControl
  20. {
  21. /// <summary>
  22. /// Interaction logic for PrintPreviewControl.xaml
  23. /// </summary>
  24. public partial class PrintPreviewControl : UserControl, INotifyPropertyChanged
  25. {
  26. private double PDFToMediaDpiRatio = 100.0 / 72.0;
  27. private double mmToDpiRatio = 100 / 25.4;
  28. private PrintSettingsInfo printSettingsInfo;
  29. private int originalPaperIndex;
  30. private string _paperIndex = "1";
  31. public string PaperIndex
  32. {
  33. get
  34. {
  35. return _paperIndex;
  36. }
  37. set
  38. {
  39. if (int.TryParse(value, out int paperIndex))
  40. {
  41. if (paperIndex > 0 && paperIndex <= printSettingsInfo.TargetPaperList.Count)
  42. {
  43. originalPaperIndex = paperIndex;
  44. if (UpdateProper(ref _paperIndex, value))
  45. {
  46. TargetPaperIndex = paperIndex - 1;
  47. }
  48. }
  49. else
  50. {
  51. OnPropertyChanged();
  52. }
  53. }
  54. else if (value == string.Empty)
  55. {
  56. _paperIndex = value;
  57. }
  58. }
  59. }
  60. private int _printedPageCount;
  61. public int PrintedPageCount
  62. {
  63. get => _printedPageCount;
  64. set => UpdateProper(ref _printedPageCount, value);
  65. }
  66. private string _paperType;
  67. public string PaperKind
  68. {
  69. get => _paperType;
  70. set => UpdateProper(ref _paperType, value);
  71. }
  72. private string _paperWidth;
  73. public string PaperWidth
  74. {
  75. get => _paperWidth;
  76. set => UpdateProper(ref _paperWidth, value);
  77. }
  78. private string _paperHeight;
  79. public string PaperHeight
  80. {
  81. get => _paperHeight;
  82. set => UpdateProper(ref _paperHeight, value);
  83. }
  84. private string _viewBoxWidth = "0";
  85. public string ViewBoxWidth
  86. {
  87. get => _viewBoxWidth;
  88. set => UpdateProper(ref _viewBoxWidth, value);
  89. }
  90. private string _viewBoxHeight = "0";
  91. public string ViewBoxHeight
  92. {
  93. get => _viewBoxHeight;
  94. set => UpdateProper(ref _viewBoxHeight, value);
  95. }
  96. private BitmapSource _priviewBitmapSource;
  97. public BitmapSource PreviewBitmapSource
  98. {
  99. get => _priviewBitmapSource;
  100. set => UpdateProper(ref _priviewBitmapSource, value);
  101. }
  102. private Thickness _margins;
  103. public Thickness Margins
  104. {
  105. get => _margins;
  106. set => UpdateProper(ref _margins, value);
  107. }
  108. private int _targetPaperIndex = 0;
  109. private Bitmap blankPageBitmap;
  110. public int TargetPaperIndex
  111. {
  112. get => _targetPaperIndex;
  113. set
  114. {
  115. if (UpdateProper(ref _targetPaperIndex, value))
  116. {
  117. JumpToSelectedPage();
  118. }
  119. }
  120. }
  121. public void SetViewBox(double height, double width)
  122. {
  123. if (height / width >= (248.0 / 180.0))
  124. {
  125. ViewBoxHeight = "248.0";
  126. ViewBoxWidth = (width / height * 248.0).ToString();
  127. Margins = new Thickness()
  128. {
  129. Left = printSettingsInfo.Margins.Left * (248.0 / printSettingsInfo.PaperSize.Height),
  130. Right = printSettingsInfo.Margins.Right * (248.0 / printSettingsInfo.PaperSize.Height),
  131. Top = printSettingsInfo.Margins.Top * (248.0 / printSettingsInfo.PaperSize.Height),
  132. Bottom = printSettingsInfo.Margins.Bottom * (248.0 / printSettingsInfo.PaperSize.Height)
  133. };
  134. }
  135. else
  136. {
  137. ViewBoxWidth = "180.0";
  138. ViewBoxHeight = (height / width * 180.0).ToString();
  139. Margins = new Thickness()
  140. {
  141. Left = printSettingsInfo.Margins.Left * (180.0 / printSettingsInfo.PaperSize.Width),
  142. Right = printSettingsInfo.Margins.Right * (180.0 / printSettingsInfo.PaperSize.Width),
  143. Top = printSettingsInfo.Margins.Top * (180.0 / printSettingsInfo.PaperSize.Width),
  144. Bottom = printSettingsInfo.Margins.Bottom * (180.0 / printSettingsInfo.PaperSize.Width)
  145. };
  146. }
  147. }
  148. private void SetPreviewBox()
  149. {
  150. PaperKind = printSettingsInfo.PaperSize.Kind.ToString();
  151. if (printSettingsInfo.PrintOrientation == PageOrientation.Portrait)
  152. {
  153. SetPortrait();
  154. }
  155. else if (printSettingsInfo.PrintOrientation == PageOrientation.Landscape)
  156. {
  157. SetLandscape();
  158. }
  159. else
  160. {
  161. CPDFPage page = printSettingsInfo.Document.PageAtIndex(printSettingsInfo.TargetPaperList[TargetPaperIndex]);
  162. if (page.PageSize.height > page.PageSize.width)
  163. {
  164. SetPortrait();
  165. }
  166. else
  167. {
  168. SetLandscape();
  169. }
  170. }
  171. if (!(printSettingsInfo.PrintMode is PosterModeInfo))
  172. {
  173. SetViewBox(double.Parse(PaperHeight), double.Parse(PaperWidth));
  174. }
  175. void SetPortrait()
  176. {
  177. PaperWidth = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Width));
  178. PaperHeight = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Height));
  179. }
  180. void SetLandscape()
  181. {
  182. PaperWidth = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Height));
  183. PaperHeight = string.Format("{0:F1}", (printSettingsInfo.PaperSize.Width));
  184. }
  185. }
  186. internal void Init(PrintSettingsInfo printSettingsInfo, bool needPageReset = false)
  187. {
  188. this.printSettingsInfo = printSettingsInfo;
  189. PrintedPageCount = PrintHelper.CaculatePrintedPageCount(printSettingsInfo);
  190. CalculatePaperCollection(needPageReset);
  191. SetPreviewBox();
  192. PaintPageByCurrentPreviewIndex();
  193. }
  194. private void CreateBlankBitmap()
  195. {
  196. CPDFPage page = printSettingsInfo.Document.PageAtIndex(printSettingsInfo.TargetPaperList[TargetPaperIndex]);
  197. double height = 0;
  198. double width = 0;
  199. width = printSettingsInfo.PrintOrientation == PageOrientation.Portrait
  200. ? printSettingsInfo.ActualWidth
  201. : printSettingsInfo.ActualHeight;
  202. height = printSettingsInfo.PrintOrientation == PageOrientation.Portrait
  203. ? printSettingsInfo.ActualHeight
  204. : printSettingsInfo.ActualWidth;
  205. blankPageBitmap = new Bitmap((int)width, (int)height);
  206. using (Graphics g = Graphics.FromImage(blankPageBitmap))
  207. {
  208. g.Clear(Color.White);
  209. }
  210. }
  211. public void CalculatePaperCollection(bool needPageReset = false)
  212. {
  213. printSettingsInfo.TargetPaperList = new List<int>(printSettingsInfo.PageRangeList);
  214. if (printSettingsInfo.IsReverseOrder)
  215. {
  216. printSettingsInfo.TargetPaperList.Reverse();
  217. }
  218. if (needPageReset)
  219. {
  220. PaperIndex = "1";
  221. }
  222. }
  223. public PrintPreviewControl()
  224. {
  225. InitializeComponent();
  226. DataContext = this;
  227. }
  228. private readonly object lockObject = new object();
  229. private void PaintPageByCurrentPreviewIndex()
  230. {
  231. lock (lockObject)
  232. {
  233. CreateBlankBitmap();
  234. PreviewPageBySizeMode(printSettingsInfo.TargetPaperList[TargetPaperIndex]);
  235. }
  236. }
  237. [System.Runtime.InteropServices.DllImport("gdi32.dll")]
  238. public static extern bool DeleteObject(IntPtr hObject);
  239. public BitmapSource ToBitmapSource(System.Drawing.Bitmap bmp)
  240. {
  241. IntPtr ptr = bmp.GetHbitmap();//obtain the Hbitmap
  242. try
  243. {
  244. BitmapSource bmpsrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap
  245. (
  246. ptr,
  247. IntPtr.Zero,
  248. new Int32Rect(0, 0, bmp.Width, bmp.Height),
  249. System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()
  250. );
  251. return bmpsrc;
  252. }
  253. finally
  254. {
  255. DeleteObject(ptr);
  256. }
  257. }
  258. public Bitmap Resize(Bitmap input, int targetWidth, int targetHeight)
  259. {
  260. try
  261. {
  262. var actualBitmap = new Bitmap(targetWidth, targetHeight);
  263. var g = Graphics.FromImage(actualBitmap);
  264. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  265. g.DrawImage(input,
  266. new Rectangle(0, 0, targetWidth, targetHeight),
  267. new Rectangle(0, 0, input.Width, input.Height),
  268. GraphicsUnit.Pixel);
  269. g.Dispose();
  270. return actualBitmap;
  271. }
  272. catch (Exception ex)
  273. {
  274. return null;
  275. }
  276. }
  277. private void PreviewPageBySizeMode(int index)
  278. {
  279. if (!(printSettingsInfo.PrintMode is SizeModeInfo sizeModeInfo))
  280. {
  281. return;
  282. }
  283. Bitmap printBitmap = new Bitmap((int)double.Parse(PaperWidth), (int)double.Parse(PaperHeight));
  284. CPDFPage page = printSettingsInfo.Document.PageAtIndex(index);
  285. CSize cSize = page.PageSize;
  286. System.Drawing.Size pageSize = new System.Drawing.Size((int)cSize.width, (int)cSize.height);
  287. CRect pageRect = new CRect(0, (int)(pageSize.Height), (int)(pageSize.Width), 0);
  288. byte[] bmpData = new byte[(int)(pageRect.width() * pageRect.height() * 4)];
  289. if (page != null)
  290. {
  291. Bitmap bitmap = null;
  292. if (PrintHelper.IsPageHaveSignAP(page))
  293. {
  294. bitmap = PrintHelper.GetPageBitmapWithFormDynamicAP(printSettingsInfo.Document, page, 1, 1, pageRect, 0xFFFFFFFF, bmpData, printSettingsInfo.IsPrintAnnot ? 1 : 0, printSettingsInfo.IsPrintForm);
  295. }
  296. if (bitmap == null)
  297. {
  298. page.RenderPageBitmapWithMatrix((float)1, pageRect, 0xFFFFFFFF, bmpData, printSettingsInfo.IsPrintAnnot ? 1 : 0, printSettingsInfo.IsPrintForm);
  299. bitmap = PrintHelper.BuildBmp((int)pageRect.width(), (int)pageRect.height(), bmpData);
  300. }
  301. Point startPoint = new Point(0, 0);
  302. if (printSettingsInfo.IsGrayscale)
  303. {
  304. bitmap = PrintHelper.ToGray(bitmap, 0);
  305. }
  306. if (sizeModeInfo.SizeType == SizeType.Adaptive)
  307. {
  308. int resizedHeight = 0;
  309. int resizedWidth = 0;
  310. if (bitmap.Height / bitmap.Width >= (printSettingsInfo.ActualHeight / printSettingsInfo.ActualWidth))
  311. {
  312. if (printSettingsInfo.PrintOrientation == PageOrientation.Portrait)
  313. {
  314. resizedHeight = (int)printSettingsInfo.ActualHeight;
  315. resizedWidth = (int)(printSettingsInfo.ActualHeight / bitmap.Height * bitmap.Width);
  316. }
  317. else
  318. {
  319. resizedWidth = (int)printSettingsInfo.ActualHeight;
  320. resizedHeight = (int)(printSettingsInfo.ActualHeight / bitmap.Height * bitmap.Width);
  321. }
  322. }
  323. else
  324. {
  325. if (printSettingsInfo.PrintOrientation == PageOrientation.Portrait)
  326. {
  327. resizedWidth = (int)printSettingsInfo.ActualWidth;
  328. resizedHeight = (int)printSettingsInfo.ActualHeight;
  329. }
  330. else
  331. {
  332. resizedHeight = (int)printSettingsInfo.ActualWidth;
  333. resizedWidth = (int)printSettingsInfo.ActualHeight;
  334. }
  335. }
  336. bitmap = Resize(bitmap, resizedWidth, resizedHeight);
  337. startPoint.X = (blankPageBitmap.Width - resizedWidth) / 2;
  338. startPoint.Y = (blankPageBitmap.Height - resizedHeight) / 2;
  339. printBitmap = PrintHelper.CombineBitmap(blankPageBitmap, bitmap, startPoint);
  340. }
  341. else if (sizeModeInfo.SizeType == SizeType.Actural)
  342. {
  343. bitmap = PrintHelper.ResizeBitmap(bitmap, 100);
  344. startPoint.X = (blankPageBitmap.Width - bitmap.Width) / 2;
  345. startPoint.Y = (blankPageBitmap.Height - bitmap.Height) / 2;
  346. printBitmap = PrintHelper.CombineBitmap(blankPageBitmap, bitmap, startPoint);
  347. }
  348. else
  349. {
  350. float scale = sizeModeInfo.SizeType == SizeType.Customized ? sizeModeInfo.Scale : 1;
  351. bitmap = PrintHelper.ResizeBitmap(bitmap, scale);
  352. startPoint.X = (blankPageBitmap.Width - bitmap.Width) / 2;
  353. startPoint.Y = (blankPageBitmap.Height - bitmap.Height) / 2;
  354. printBitmap = PrintHelper.CombineBitmap(blankPageBitmap, bitmap, startPoint);
  355. }
  356. }
  357. PreviewBitmapSource = ToBitmapSource(printBitmap);
  358. }
  359. public void JumpToSelectedPage()
  360. {
  361. PaintPageByCurrentPreviewIndex();
  362. }
  363. public event PropertyChangedEventHandler PropertyChanged;
  364. protected bool UpdateProper<T>(ref T properValue,
  365. T newValue,
  366. [CallerMemberName] string properName = "")
  367. {
  368. if (object.Equals(properValue, newValue))
  369. return false;
  370. properValue = newValue;
  371. OnPropertyChanged(properName);
  372. return true;
  373. }
  374. protected void OnPropertyChanged([CallerMemberName] string propertyName = "") =>
  375. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  376. private void btnPreButton_Click(object sender, RoutedEventArgs e)
  377. {
  378. if (!int.TryParse(PaperIndex, out int _))
  379. {
  380. _paperIndex = originalPaperIndex.ToString();
  381. }
  382. PaperIndex = (int.Parse(PaperIndex) - 1).ToString();
  383. }
  384. private void btnNextButton_Click(object sender, RoutedEventArgs e)
  385. {
  386. if (!int.TryParse(PaperIndex, out int _))
  387. {
  388. _paperIndex = originalPaperIndex.ToString();
  389. }
  390. PaperIndex = (int.Parse(PaperIndex) + 1).ToString();
  391. }
  392. private void txbPageIndex_LostFocus(object sender, RoutedEventArgs e)
  393. {
  394. if (PaperIndex == string.Empty)
  395. {
  396. PaperIndex = (originalPaperIndex).ToString();
  397. }
  398. }
  399. private void txbPageIndex_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
  400. {
  401. if (e.NewFocus is Button button && (button == btnNextButton || button == btnPreButton))
  402. {
  403. e.Handled = true;
  404. }
  405. }
  406. }
  407. }