PrintPreviewControl.xaml.cs 16 KB

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