PrintPreviewControl.xaml.cs 14 KB

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