PrintHelper.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. using ComPDFKit.Controls.PDFControl;
  2. using ComPDFKit.DigitalSign;
  3. using ComPDFKit.Import;
  4. using ComPDFKit.PDFAnnotation;
  5. using ComPDFKit.PDFAnnotation.Form;
  6. using ComPDFKit.PDFDocument;
  7. using ComPDFKit.PDFPage;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Drawing;
  11. using System.Drawing.Imaging;
  12. using System.Drawing.Printing;
  13. using System.Linq;
  14. using System.Printing;
  15. using System.Reflection;
  16. using System.Runtime.InteropServices;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. using System.Windows.Forms;
  20. using System.Windows.Media;
  21. namespace ComPDFKit.Controls.Printer
  22. {
  23. public enum DuplexingStage
  24. {
  25. None,
  26. FontSide,
  27. BackSide
  28. }
  29. public static class PrintHelper
  30. {
  31. private static PrintSettingsInfo printSettingsInfo;
  32. private static int MaxCopies = 1;
  33. private static bool FinishedFrontSide = false;
  34. private static bool isManualDuplex = false;
  35. private static List<OutputColor> outputColors;
  36. private static List<Duplexing> duplexings;
  37. private static Bitmap blankPageBitmapForPrint;
  38. private static int PrintIndex;
  39. public static PrintQueue printQueue;
  40. public static void InitPrint()
  41. {
  42. MaxCopies = 1;
  43. FinishedFrontSide = false;
  44. isManualDuplex = false;
  45. outputColors = new List<OutputColor>();
  46. duplexings = new List<Duplexing>();
  47. blankPageBitmapForPrint = null;
  48. PrintIndex = 0;
  49. }
  50. private static void SetPrinterLimits()
  51. {
  52. MaxCopies = printQueue.GetPrintCapabilities().MaxCopyCount.HasValue ? printQueue.GetPrintCapabilities().MaxCopyCount.Value : 1;
  53. outputColors = new List<OutputColor>(printQueue.GetPrintCapabilities().OutputColorCapability);
  54. duplexings = new List<Duplexing>(printQueue.GetPrintCapabilities().DuplexingCapability);
  55. }
  56. public static PrintQueue GetPrintQueue(PrintServer server, string printerName)
  57. {
  58. return server.GetPrintQueue(printerName);
  59. }
  60. public static void PrintDocument(PrintSettingsInfo printSettings)
  61. {
  62. printSettingsInfo = printSettings;
  63. SetPrinterLimits();
  64. if (printSettings.DuplexPrintMod == DuplexPrintMod.None ||
  65. (printSettings.PrintMode is BookletModeInfo bookletModeInfo && bookletModeInfo.Subset != BookletSubset.BothSides))
  66. {
  67. HandlePrintQueue(DuplexingStage.None);
  68. }
  69. else if (printSettings.DuplexPrintMod > 0 ||
  70. (printSettings.PrintMode is BookletModeInfo bookletModeInfo1 && bookletModeInfo1.Subset == BookletSubset.BothSides))
  71. {
  72. if (duplexings.Contains(Duplexing.TwoSidedShortEdge) || duplexings.Contains(Duplexing.TwoSidedLongEdge))
  73. {
  74. HandlePrintQueue(DuplexingStage.None);
  75. }
  76. else
  77. {
  78. if (OnlyOnePage())
  79. {
  80. HandlePrintQueue(DuplexingStage.None);
  81. }
  82. else
  83. {
  84. HandlePrintQueue(DuplexingStage.FontSide);
  85. if (FinishedFrontSide)
  86. {
  87. DialogResult dialogResult = MessageBox.Show("Print the back side.", "Print", MessageBoxButtons.YesNo);
  88. if (dialogResult == DialogResult.Yes)
  89. {
  90. HandlePrintQueue(DuplexingStage.BackSide);
  91. }
  92. }
  93. }
  94. }
  95. }
  96. bool OnlyOnePage()
  97. {
  98. return ((printSettings.PrintMode is SizeModeInfo || printSettings.PrintMode is PosterModeInfo) &&
  99. printSettings.PageRangeList.Count == 1) ||
  100. (printSettings.PrintMode is MultipleModeInfo multipleModeInfo &&
  101. (int)Math.Ceiling(printSettings.PageRangeList.Count / (double)(multipleModeInfo.Sheet.TotalPageNumber)) == 1);
  102. }
  103. }
  104. private static void HandlePrintQueue(DuplexingStage stage)
  105. {
  106. if (printQueue != null)
  107. {
  108. using (var printDocument = new PrintDocument())
  109. {
  110. var printTicket = new PrintTicket();
  111. printDocument.PrinterSettings.PrinterName = printQueue.Name;
  112. printDocument.DefaultPageSettings.Color = !printSettingsInfo.IsGrayscale && outputColors.Contains(OutputColor.Color);
  113. printTicket.PageOrientation = printSettingsInfo.PrintOrientation;
  114. if (printSettingsInfo.DuplexPrintMod > 0 || printSettingsInfo.PrintMode is BookletModeInfo)
  115. {
  116. if (stage == DuplexingStage.None)
  117. {
  118. if (printSettingsInfo.DuplexPrintMod == DuplexPrintMod.FlipLongEdge)
  119. {
  120. printDocument.PrinterSettings.Duplex = Duplex.Horizontal;
  121. }
  122. else
  123. {
  124. printDocument.PrinterSettings.Duplex = Duplex.Vertical;
  125. }
  126. PrintIndex = 0;
  127. }
  128. else
  129. {
  130. printDocument.PrinterSettings.Duplex = Duplex.Simplex;
  131. isManualDuplex = true;
  132. PrintIndex = stage == DuplexingStage.FontSide ? 0 : 1;
  133. }
  134. }
  135. else
  136. {
  137. printDocument.PrinterSettings.Duplex = Duplex.Simplex;
  138. PrintIndex = 0;
  139. }
  140. printQueue.DefaultPrintTicket = printTicket;
  141. printDocument.DefaultPageSettings.PaperSize = printSettingsInfo.PaperSize;
  142. printDocument.DefaultPageSettings.Landscape = (printSettingsInfo.PrintOrientation == PageOrientation.Landscape);
  143. List<PaperSource> paperSources;
  144. if (printDocument.PrinterSettings.PaperSources.Count > 0)
  145. {
  146. paperSources = Enumerable.Range(0, printDocument.PrinterSettings.PaperSources.Count).
  147. Select(i => printDocument.PrinterSettings.PaperSources[i]).ToList();
  148. }
  149. else
  150. {
  151. PaperSource defaultPaperSource = new PaperSource();
  152. defaultPaperSource.SourceName = "Default";
  153. paperSources = new List<PaperSource> { defaultPaperSource };
  154. }
  155. printDocument.DefaultPageSettings.Margins = new Margins() { Left = (int)printSettingsInfo.Margins.Left, Bottom = (int)printSettingsInfo.Margins.Bottom, Right = (int)printSettingsInfo.Margins.Right, Top = (int)printSettingsInfo.Margins.Top};
  156. if (printSettingsInfo.Copies >= printQueue.GetPrintCapabilities().MaxCopyCount)
  157. {
  158. printDocument.PrinterSettings.Copies = (short)MaxCopies;
  159. }
  160. else
  161. {
  162. printDocument.PrinterSettings.Copies = (short)printSettingsInfo.Copies;
  163. }
  164. printDocument.PrintPage -= PrintDocument_PrintPage;
  165. printDocument.PrintPage += PrintDocument_PrintPage;
  166. printDocument.PrinterSettings.PrintFileName = printSettingsInfo.Document.FileName;
  167. try
  168. {
  169. printDocument.Print();
  170. if(stage == DuplexingStage.FontSide)
  171. {
  172. FinishedFrontSide = true;
  173. }
  174. }
  175. catch (Exception ex)
  176. {
  177. MessageBox.Show(ex.Message);
  178. }
  179. }
  180. }
  181. }
  182. public static Bitmap ToGray(Bitmap bmp, int mode)
  183. {
  184. if (bmp == null)
  185. {
  186. return null;
  187. }
  188. int w = bmp.Width;
  189. int h = bmp.Height;
  190. try
  191. {
  192. byte newColor = 0;
  193. BitmapData srcData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
  194. unsafe
  195. {
  196. byte* p = (byte*)srcData.Scan0.ToPointer();
  197. for (int y = 0; y < h; y++)
  198. {
  199. for (int x = 0; x < w; x++)
  200. {
  201. if (mode == 0)
  202. {
  203. newColor = (byte)((float)p[0] * 0.114f + (float)p[1] * 0.587f + (float)p[2] * 0.299f);
  204. }
  205. else
  206. {
  207. newColor = (byte)((float)(p[0] + p[1] + p[2]) / 3.0f);
  208. }
  209. p[0] = newColor;
  210. p[1] = newColor;
  211. p[2] = newColor;
  212. p += 3;
  213. }
  214. p += srcData.Stride - w * 3;
  215. }
  216. bmp.UnlockBits(srcData);
  217. return bmp;
  218. }
  219. }
  220. catch
  221. {
  222. return null;
  223. }
  224. }
  225. public static Bitmap BuildBmp(int width, int height, byte[] imgBytes)
  226. {
  227. // Check if the byte array length matches the expected size
  228. int expectedLength = width * height * 4;
  229. if (imgBytes.Length != expectedLength)
  230. {
  231. throw new ArgumentException("The length of imgBytes does not match the expected size.");
  232. }
  233. // Create a new bitmap with the specified width, height, and pixel format
  234. Bitmap bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  235. // Lock the bitmap's bits for writing
  236. BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
  237. try
  238. {
  239. // Copy the byte array to the bitmap's scan0 pointer
  240. Marshal.Copy(imgBytes, 0, bmpData.Scan0, imgBytes.Length);
  241. }
  242. finally
  243. {
  244. // Ensure that the bitmap is always unlocked, even if an exception occurs
  245. bitmap.UnlockBits(bmpData);
  246. }
  247. return bitmap;
  248. }
  249. public static int CaculatePrintedPageCount(PrintSettingsInfo printSettingsInfo)
  250. {
  251. int tempCount = printSettingsInfo.PageRangeList.Count;
  252. if (printSettingsInfo.PrintMode is MultipleModeInfo multipleModeInfo)
  253. {
  254. tempCount = (int)Math.Ceiling((double)tempCount /
  255. multipleModeInfo.Sheet.TotalPageNumber);
  256. }
  257. else if (printSettingsInfo.PrintMode is BookletModeInfo bookletInfo)
  258. {
  259. if (tempCount != 1)
  260. {
  261. tempCount = (bookletInfo.EndPageIndex - bookletInfo.BeginPageIndex + 1) / 2;
  262. if (bookletInfo.Subset != BookletSubset.BothSides)
  263. {
  264. tempCount /= 2;
  265. }
  266. }
  267. }
  268. return tempCount;
  269. }
  270. public static Bitmap CombineBitmap(Bitmap background, Bitmap foreground, System.Drawing.Point point)
  271. {
  272. if (background == null)
  273. {
  274. return null;
  275. }
  276. int bgWidth = background.Width;
  277. int bgHeight = background.Height;
  278. Bitmap newMap = new Bitmap(bgWidth, bgHeight);
  279. Graphics graphics = Graphics.FromImage(newMap);
  280. graphics.DrawImage(background, new System.Drawing.Point(0, 0));
  281. graphics.DrawImage(foreground, point);
  282. graphics.Dispose();
  283. return newMap;
  284. }
  285. private static void PrintDocumentModSize(PrintPageEventArgs e)
  286. {
  287. int PrintedPageCount = CaculatePrintedPageCount(printSettingsInfo);
  288. int widthDpiRatio = (int)e.Graphics.DpiX / 100;
  289. int heightDpiRatio = (int)e.Graphics.DpiY / 100;
  290. if (printSettingsInfo.PrintMode is SizeModeInfo sizeMode)
  291. {
  292. CPDFPage page = printSettingsInfo.Document.PageAtIndex(printSettingsInfo.TargetPaperList[PrintIndex]);
  293. Rectangle realBound = e.PageBounds;
  294. if (!printSettingsInfo.IsBorderless)
  295. {
  296. realBound.Width = realBound.Width - (int)printSettingsInfo.Margins.Left - (int)printSettingsInfo.Margins.Right;
  297. realBound.Height = realBound.Height - (int)printSettingsInfo.Margins.Top - (int)printSettingsInfo.Margins.Bottom;
  298. }
  299. Margins margins = e.PageSettings.Margins;
  300. Point point = new Point(0, 0);
  301. if (page != null)
  302. {
  303. CSize cSize = page.PageSize;
  304. System.Drawing.Size pageSize = new System.Drawing.Size((int)cSize.width * widthDpiRatio, (int)cSize.height * heightDpiRatio);
  305. byte[] bmpData = new byte[(int)(pageSize.Width * pageSize.Height * 4)];
  306. Bitmap bitmap = null;
  307. if (PrintHelper.IsPageHaveSignAP(page))
  308. {
  309. bitmap = GetPageBitmapWithFormDynamicAP(printSettingsInfo.Document, page, widthDpiRatio, heightDpiRatio, new CRect(0, pageSize.Height, pageSize.Width, 0), 0xFFFFFFFF, bmpData, printSettingsInfo.IsPrintAnnot ? 1 : 0, printSettingsInfo.IsPrintForm);
  310. }
  311. if (bitmap == null)
  312. {
  313. page.RenderPageBitmap(0, 0, pageSize.Width, pageSize.Height, 0xFFFFFFFF, bmpData, printSettingsInfo.IsPrintAnnot ? 1 : 0, printSettingsInfo.IsPrintForm);
  314. bitmap = BuildBmp((int)pageSize.Width, (int)pageSize.Height, bmpData);
  315. }
  316. if (printSettingsInfo.IsGrayscale)
  317. {
  318. bitmap = ToGray(bitmap, 0);
  319. }
  320. if (sizeMode.SizeType == SizeType.Adaptive)
  321. {
  322. int resizeHeight;
  323. int resizeWidth;
  324. if (bitmap.Height / bitmap.Width >= (printSettingsInfo.ActualHeight / printSettingsInfo.ActualWidth))
  325. {
  326. if (printSettingsInfo.PrintOrientation == PageOrientation.Portrait)
  327. {
  328. resizeHeight = (int)printSettingsInfo.ActualHeight;
  329. resizeWidth = (int)(printSettingsInfo.ActualHeight / bitmap.Height * bitmap.Width);
  330. }
  331. else
  332. {
  333. resizeWidth = (int)printSettingsInfo.ActualHeight;
  334. resizeHeight = (int)(printSettingsInfo.ActualHeight / bitmap.Height * bitmap.Width);
  335. }
  336. }
  337. else
  338. {
  339. if (printSettingsInfo.PrintOrientation == PageOrientation.Portrait)
  340. {
  341. resizeWidth = (int)printSettingsInfo.ActualWidth;
  342. resizeHeight = (int)(printSettingsInfo.ActualWidth / bitmap.Width * bitmap.Height);
  343. }
  344. else
  345. {
  346. resizeHeight = (int)printSettingsInfo.ActualWidth;
  347. resizeWidth = (int)(printSettingsInfo.ActualWidth / bitmap.Height * bitmap.Width);
  348. }
  349. }
  350. using (Bitmap resizedBitmap = new Bitmap(bitmap, resizeWidth * widthDpiRatio, resizeHeight * heightDpiRatio))
  351. {
  352. if (isManualDuplex && PrintIndex % 2 == 1 && printSettingsInfo.DuplexPrintMod == DuplexPrintMod.FlipShortEdge)
  353. {
  354. resizedBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
  355. }
  356. float aspectRatioResizedBitmap = (float)resizedBitmap.Width / resizedBitmap.Height;
  357. float aspectRatioRealBound = (float)realBound.Width / realBound.Height;
  358. if (aspectRatioResizedBitmap != aspectRatioRealBound)
  359. {
  360. if (realBound.Width / aspectRatioResizedBitmap <= realBound.Height)
  361. {
  362. realBound.Height = (int)(realBound.Width / aspectRatioResizedBitmap);
  363. }
  364. else
  365. {
  366. realBound.Width = (int)(realBound.Height * aspectRatioResizedBitmap);
  367. }
  368. }
  369. int originX = (e.PageBounds.Width - realBound.Width)/2;
  370. int originY = (e.PageBounds.Height - realBound.Height)/2;
  371. if (!printSettingsInfo.IsBorderless)
  372. {
  373. if (originX < printSettingsInfo.Margins.Left)
  374. {
  375. originX = (int)printSettingsInfo.Margins.Left;
  376. }
  377. if (originY < printSettingsInfo.Margins.Top)
  378. {
  379. originY = (int)printSettingsInfo.Margins.Top;
  380. }
  381. }
  382. e.Graphics.DrawImage(resizedBitmap, new Rectangle(originX, originY, realBound.Width, realBound.Height), new Rectangle(0, 0, resizedBitmap.Width, resizedBitmap.Height), GraphicsUnit.Pixel);
  383. }
  384. }
  385. else if (sizeMode.SizeType == SizeType.Actural)
  386. {
  387. using (Bitmap resizedBitmap = ResizeBitmap(bitmap, 100))
  388. {
  389. realBound.Width = (int)(cSize.width * 1.4);
  390. realBound.Height = (int)(cSize.height * 1.4);
  391. if (isManualDuplex && PrintIndex % 2 == 1 && printSettingsInfo.DuplexPrintMod == DuplexPrintMod.FlipShortEdge)
  392. {
  393. resizedBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
  394. }
  395. float aspectRatioResizedBitmap = (float)resizedBitmap.Width / resizedBitmap.Height;
  396. float aspectRatioRealBound = (float)realBound.Width / realBound.Height;
  397. if (aspectRatioResizedBitmap != aspectRatioRealBound)
  398. {
  399. if (realBound.Width / aspectRatioResizedBitmap <= realBound.Height)
  400. {
  401. realBound.Height = (int)(realBound.Width / aspectRatioResizedBitmap);
  402. }
  403. else
  404. {
  405. realBound.Width = (int)(realBound.Height * aspectRatioResizedBitmap);
  406. }
  407. }
  408. int originX = (e.PageBounds.Width - realBound.Width) / 2;
  409. int originY = (e.PageBounds.Height - realBound.Height) / 2;
  410. if (!printSettingsInfo.IsBorderless)
  411. {
  412. if (originX < printSettingsInfo.Margins.Left)
  413. {
  414. originX = (int)printSettingsInfo.Margins.Left;
  415. }
  416. if (originY < printSettingsInfo.Margins.Top)
  417. {
  418. originY = (int)printSettingsInfo.Margins.Top;
  419. }
  420. }
  421. e.Graphics.DrawImage(resizedBitmap, new Rectangle(originX, originY, realBound.Width, realBound.Height), new Rectangle(0, 0, resizedBitmap.Width, resizedBitmap.Height), GraphicsUnit.Pixel);
  422. }
  423. }
  424. else if (sizeMode.SizeType == SizeType.Customized)
  425. {
  426. using (Bitmap resizedBitmap = ResizeBitmap(bitmap, (printSettingsInfo.PrintMode as SizeModeInfo).Scale))
  427. {
  428. if (isManualDuplex && PrintIndex % 2 == 1 && printSettingsInfo.DuplexPrintMod == DuplexPrintMod.FlipShortEdge)
  429. {
  430. resizedBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
  431. }
  432. float aspectRatioResizedBitmap = (float)resizedBitmap.Width / resizedBitmap.Height;
  433. float aspectRatioRealBound = (float)realBound.Width / realBound.Height;
  434. realBound.Width = (int)(cSize.width * 1.4);
  435. realBound.Height = (int)(cSize.height * 1.4);
  436. realBound.Width = (int)(realBound.Width * (printSettingsInfo.PrintMode as SizeModeInfo).Scale / 100.0);
  437. realBound.Height = (int)(realBound.Height * (printSettingsInfo.PrintMode as SizeModeInfo).Scale / 100.0);
  438. if (aspectRatioResizedBitmap != aspectRatioRealBound)
  439. {
  440. if (realBound.Width / aspectRatioResizedBitmap <= realBound.Height)
  441. {
  442. realBound.Height = (int)(realBound.Width / aspectRatioResizedBitmap);
  443. }
  444. else
  445. {
  446. realBound.Width = (int)(realBound.Height * aspectRatioResizedBitmap);
  447. }
  448. }
  449. int originX = (e.PageBounds.Width - realBound.Width) / 2;
  450. int originY = (e.PageBounds.Height - realBound.Height) / 2;
  451. if (!printSettingsInfo.IsBorderless)
  452. {
  453. if (originX < printSettingsInfo.Margins.Left)
  454. {
  455. originX = (int)printSettingsInfo.Margins.Left;
  456. }
  457. if (originY < printSettingsInfo.Margins.Top)
  458. {
  459. originY = (int)printSettingsInfo.Margins.Top;
  460. }
  461. }
  462. e.Graphics.DrawImage(resizedBitmap, new Rectangle(originX, originY, realBound.Width, realBound.Height), new Rectangle(0, 0, resizedBitmap.Width, resizedBitmap.Height), GraphicsUnit.Pixel);
  463. }
  464. }
  465. bitmap.Dispose();
  466. GC.Collect();
  467. if (isManualDuplex && PrintedPageCount != 1)
  468. {
  469. if (PrintIndex < PrintedPageCount - 2)
  470. {
  471. PrintIndex += 2;
  472. e.HasMorePages = true;
  473. }
  474. else
  475. {
  476. e.HasMorePages = false;
  477. if (PrintIndex % 2 == 0)
  478. {
  479. //
  480. }
  481. }
  482. }
  483. else
  484. {
  485. if (PrintIndex < PrintedPageCount - 1)
  486. {
  487. PrintIndex++;
  488. e.HasMorePages = true;
  489. }
  490. else
  491. {
  492. e.HasMorePages = false;
  493. }
  494. }
  495. }
  496. }
  497. }
  498. private static void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
  499. {
  500. switch (printSettingsInfo.PrintMode)
  501. {
  502. case SizeModeInfo _:
  503. PrintDocumentModSize(e);
  504. break;
  505. case PosterModeInfo _:
  506. break;
  507. case MultipleModeInfo _:
  508. break;
  509. case BookletModeInfo _:
  510. break;
  511. }
  512. }
  513. internal static Bitmap ResizeBitmap(Bitmap bitmap, float scale)
  514. {
  515. int newWidth = (int)(bitmap.Width * scale / 72);
  516. int newHeight = (int)(bitmap.Height * scale / 72);
  517. Bitmap newBitmap = new Bitmap(newWidth, newHeight);
  518. using (Graphics g = Graphics.FromImage(newBitmap))
  519. {
  520. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
  521. g.DrawImage(bitmap, 0, 0, newWidth, newHeight);
  522. }
  523. return newBitmap;
  524. }
  525. public static Bitmap GetPageBitmapWithFormDynamicAP(CPDFDocument pdfDoc, CPDFPage page,float scaleX,float scaleY, CRect rangeRect,uint bgColor, byte[] bmpData, int flag, bool form = false)
  526. {
  527. if (pdfDoc==null || pdfDoc.IsValid()==false || page == null || page.IsValid() == false)
  528. {
  529. return null;
  530. }
  531. if (bmpData == null || bmpData.Length == 0)
  532. {
  533. return null;
  534. }
  535. if(scaleX==scaleY)
  536. {
  537. page.RenderPageBitmapWithMatrix(scaleX, rangeRect, bgColor, bmpData, flag, false);
  538. }
  539. else
  540. {
  541. page.RenderPageBitmap((int)rangeRect.left, (int)rangeRect.top, (int)rangeRect.width(), (int)rangeRect.height(), bgColor, bmpData, flag, false);
  542. }
  543. if (form == false)
  544. {
  545. return BuildBmp((int)rangeRect.width(), (int)rangeRect.height(), bmpData);
  546. }
  547. List<CPDFAnnotation> annotList = page.GetAnnotations();
  548. if (annotList == null || annotList.Count == 0)
  549. {
  550. return BuildBmp((int)rangeRect.width(), (int)rangeRect.height(), bmpData);
  551. }
  552. Bitmap writeBitmap = BuildBmp((int)rangeRect.width(), (int)rangeRect.height(), bmpData);
  553. Graphics drawGraph = Graphics.FromImage(writeBitmap);
  554. foreach (CPDFAnnotation rawAnnot in annotList)
  555. {
  556. if (rawAnnot.Type != C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET)
  557. {
  558. continue;
  559. }
  560. CRect annotRect = rawAnnot.GetRect();
  561. int xPos = (int)(annotRect.left * scaleX);
  562. int yPos = (int)(annotRect.top * scaleY);
  563. int annotWidth = (int)(annotRect.width()*scaleX);
  564. int annotHeight = (int)(annotRect.height()*scaleY);
  565. int renderWidth = annotWidth;
  566. int renderHeight = annotHeight;
  567. System.Windows.Rect rotateRect = new System.Windows.Rect(xPos, yPos, annotWidth, annotHeight);
  568. if (page.Rotation != 0)
  569. {
  570. Matrix rotateMatrix = new Matrix();
  571. rotateMatrix.RotateAt(-90 * page.Rotation, rotateRect.Left + annotWidth / 2, rotateRect.Top + annotHeight / 2);
  572. rotateRect.Transform(rotateMatrix);
  573. renderWidth = (int)rotateRect.Width;
  574. renderHeight = (int)rotateRect.Height;
  575. }
  576. byte[] annotData = new byte[renderWidth * renderHeight * 4];
  577. CPDFWidget widgetAnnot = rawAnnot as CPDFWidget;
  578. CPDFSignatureWidget signatureWidget = null;
  579. if (widgetAnnot.WidgetType==C_WIDGET_TYPE.WIDGET_SIGNATUREFIELDS)
  580. {
  581. signatureWidget = widgetAnnot as CPDFSignatureWidget;
  582. }
  583. bool getSignAp = false;
  584. if (signatureWidget != null && signatureWidget.IsSignAP())
  585. {
  586. CPDFSignature signature = signatureWidget.GetSignature(pdfDoc);
  587. if (signature != null)
  588. {
  589. signatureWidget.GetSignatureAppearance(renderWidth, renderHeight, annotData, signature.GetSignState());
  590. getSignAp = true;
  591. }
  592. }
  593. if (!getSignAp)
  594. {
  595. rawAnnot.RenderAnnot(renderWidth, renderHeight, annotData, CPDFAppearanceType.Normal);
  596. }
  597. Bitmap annotBitmap = BuildBmp(renderWidth, renderHeight, annotData);
  598. if (page.Rotation != 0)
  599. {
  600. switch(page.Rotation)
  601. {
  602. case 1:
  603. annotBitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
  604. break;
  605. case 2:
  606. annotBitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
  607. break;
  608. case 3:
  609. annotBitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
  610. break;
  611. }
  612. }
  613. drawGraph.DrawImage(annotBitmap,new Rectangle(xPos, yPos, annotWidth, annotHeight));
  614. }
  615. return writeBitmap;
  616. }
  617. /// <summary>
  618. /// Check whether the page has a digitally signed dynamic appearance
  619. /// </summary>
  620. /// <param name="page"></param>
  621. /// <returns></returns>
  622. public static bool IsPageHaveSignAP(CPDFPage page)
  623. {
  624. if (page == null || page.IsValid() == false)
  625. {
  626. return false;
  627. }
  628. List<CPDFAnnotation> annotList = page.GetAnnotations();
  629. if (annotList == null || annotList.Count == 0)
  630. {
  631. return false;
  632. }
  633. bool hasSignAp = false;
  634. foreach (CPDFAnnotation rawAnnot in annotList)
  635. {
  636. if (rawAnnot.Type != C_ANNOTATION_TYPE.C_ANNOTATION_WIDGET)
  637. {
  638. continue;
  639. }
  640. CPDFWidget widgetAnnot = rawAnnot as CPDFWidget;
  641. CPDFSignatureWidget signatureWidget = null;
  642. if (widgetAnnot.WidgetType == C_WIDGET_TYPE.WIDGET_SIGNATUREFIELDS)
  643. {
  644. signatureWidget = widgetAnnot as CPDFSignatureWidget;
  645. }
  646. if (signatureWidget != null && signatureWidget.IsSignAP())
  647. {
  648. hasSignAp = true;
  649. break;
  650. }
  651. }
  652. return hasSignAp;
  653. }
  654. }
  655. }