GcDocsDataSheet.cs
  1. //
  2. // This code is part of Document Solutions for PDF demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.Drawing;
  8. using System.Linq;
  9. using System.Collections.Generic;
  10. using GrapeCity.Documents.Pdf;
  11. using GrapeCity.Documents.Pdf.AcroForms;
  12. using GrapeCity.Documents.Text;
  13. using GrapeCity.Documents.Common;
  14. using GrapeCity.Documents.Drawing;
  15. using System.Numerics;
  16. using DsPdfWeb.Demos.Common;
  17.  
  18. namespace DsPdfWeb.Demos
  19. {
  20. // This sample generates a two-page data sheet about the new
  21. // Document Solutions product line.
  22. public class GcDocsDataSheet
  23. {
  24. private FontCollection _fc = new FontCollection();
  25.  
  26. Color _darkGray = Color.FromArgb(64, 64, 64);
  27. Color _lightGray = Color.FromArgb(232, 232, 232);
  28. Color _blue = Color.FromArgb(0x3B, 0x5C, 0xAA);
  29. List<IDisposable> _disposables = new List<IDisposable>();
  30.  
  31. // Main entry point of this sample:
  32. public int CreatePDF(Stream stream)
  33. {
  34. var doc = new GcPdfDocument();
  35.  
  36. _fc.RegisterDirectory(Path.Combine("Resources", "Fonts"));
  37. // First page:
  38. Page1(doc);
  39. // Second page:
  40. Page2(doc);
  41. // Save the PDF:
  42. doc.Save(stream);
  43. // Dispose images after the document has been saved:
  44. _disposables.ForEach(d_ => d_.Dispose());
  45. // Done:
  46. return doc.Pages.Count;
  47. }
  48.  
  49. IImage GetImage(string path)
  50. {
  51. var image = Util.ImageFromFile(path);
  52. _disposables.Add(image);
  53. return image;
  54. }
  55.  
  56. void Page1(GcPdfDocument doc)
  57. {
  58. var page = doc.Pages.Add();
  59. var g = page.Graphics;
  60. var tl = new TextLayout(g.Resolution) { FontCollection = _fc };
  61.  
  62. var gclogo = GetImage(Path.Combine("Resources", "ImagesBis", "gc-logo-100px.png"));
  63. var gclogoRc = new RectangleF(36, 0, 72 * 1.8f, 72);
  64. g.DrawImage(gclogo, gclogoRc, null,
  65. new ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Center, true, true, true, false, false), out RectangleF[] rcs);
  66. g.DrawLine(rcs[0].Right + 10, rcs[0].Top, rcs[0].Right + 10, rcs[0].Bottom, _darkGray, 1);
  67.  
  68. tl.Clear();
  69. tl.ParagraphAlignment = ParagraphAlignment.Center;
  70. tl.MaxHeight = gclogoRc.Height;
  71. tl.Append("Developer Solutions",
  72. new TextFormat() { FontName = "open sans", FontSize = 16, ForeColor = _darkGray });
  73. tl.PerformLayout(true);
  74. g.DrawTextLayout(tl, new PointF(gclogoRc.Right + 20, gclogoRc.Y));
  75.  
  76. var back = GetImage(Path.Combine("Resources", "ImagesBis", "GCDocs-datasheet-sm.png"));
  77. var backRcClip = new RectangleF(0, 72, page.Size.Width, page.Size.Width - 72 * 1.75f);
  78. var backRc = new RectangleF(-72, -72 * 4, page.Size.Width + 72 * 4, page.Size.Height + 72 * 4);
  79. g.DrawImage(back, backRc, backRcClip, ImageAlign.StretchImage);
  80. g.FillRectangle(new RectangleF(0, backRcClip.Bottom, page.Size.Width, page.Size.Height - backRcClip.Bottom), _lightGray);
  81. g.DrawLine(backRcClip.X, backRcClip.Bottom, backRcClip.Right, backRcClip.Bottom, Color.White, 1, null);
  82. g.DrawLine(backRcClip.X, backRcClip.Bottom + 1, backRcClip.Right, backRcClip.Bottom + 1, _darkGray, 1, null);
  83.  
  84. var blueRc = new RectangleF(0, backRcClip.Y, page.Size.Width, 72 * 4);
  85. g.FillRectangle(blueRc, Color.FromArgb(220, _blue));
  86.  
  87. blueRc.Inflate(0, -36);
  88. g.FillRectangle(new RectangleF(blueRc.Location, new SizeF(10, blueRc.Height)), Color.White);
  89.  
  90. blueRc.Inflate(-36, 0);
  91. tl.Clear();
  92. tl.ParagraphAlignment = ParagraphAlignment.Near;
  93. tl.MaxWidth = blueRc.Width;
  94. tl.MaxHeight = blueRc.Height;
  95. tl.Append("NEW PRODUCT LINE",
  96. new TextFormat() { FontName = "open sans semibold", FontSize = 20, ForeColor = Color.White });
  97. tl.PerformLayout(true);
  98. g.DrawTextLayout(tl, blueRc.Location);
  99.  
  100. var midRc = new RectangleF(blueRc.X, blueRc.Y + tl.ContentHeight, blueRc.Width, blueRc.Height - tl.ContentHeight);
  101.  
  102. tl.Clear();
  103. tl.ParagraphAlignment = ParagraphAlignment.Far;
  104. tl.Append(
  105. "Take total control of your digital documents with this NEW collection of ultra-fast, low-footprint document APIs for .NET Standard 2.0. These intuitive, extensible APIs " +
  106. "allow you to create, load, modify, and save Excel spreadsheets and PDF files in any .NET Standard 2.0 application",
  107. new TextFormat() { FontName = "open sans light", FontSize = 14, ForeColor = Color.White });
  108. tl.PerformLayout(true);
  109. g.DrawTextLayout(tl, blueRc.Location);
  110.  
  111. midRc.Height -= tl.ContentHeight;
  112. midRc.Inflate(0, -20);
  113.  
  114. var hex = GetImage(Path.Combine("Resources", "ImagesBis", "gcd-hex-logo-white.png"));
  115. var hexRc = new RectangleF(midRc.Location, new SizeF(midRc.Height, midRc.Height));
  116. g.DrawImage(hex, hexRc, null, ImageAlign.StretchImage);
  117.  
  118. tl.Clear();
  119. tl.ParagraphAlignment = ParagraphAlignment.Center;
  120. tl.MaxHeight = midRc.Height;
  121. tl.Append("Document Solutions",
  122. new TextFormat() { FontName = "open sans semibold", FontSize = 26, ForeColor = Color.White });
  123. tl.PerformLayout(true);
  124. g.DrawTextLayout(tl, new PointF(midRc.X + midRc.Height + 10, midRc.Y));
  125.  
  126. var pointRc = new RectangleF(0, backRcClip.Bottom, page.Size.Width / 2, (page.Size.Height - backRcClip.Bottom) / 2 - 12);
  127. tl.ParagraphAlignment = ParagraphAlignment.Near;
  128. tl.MaxWidth = pointRc.Width;
  129. tl.MaxHeight = pointRc.Height;
  130. tl.MarginLeft = 80;
  131. tl.MarginTop = 25;
  132. tl.MarginBottom = 0;
  133.  
  134. addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-.NET.png")),
  135. "Expand the reach of modern apps",
  136. "With full support for .NET Standard 2.0, you can target multiple platforms, devices, and cloud with one code base.");
  137.  
  138. pointRc.Offset(0, pointRc.Height);
  139. addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-code.png")),
  140. "Comprehensive, highly programmable",
  141. "Do more with your Excel spreadsheets and PDFs: these APIs support Windows, Mac, Linux, and a wide variety of features for your documents.");
  142.  
  143. pointRc.Offset(pointRc.Width, -pointRc.Height);
  144. tl.MarginRight = 30;
  145. addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-speed.png")),
  146. "High-speed, small footprint",
  147. "The API architecture is designed to generate large, optimized documents, fast—while remaining lightweight and extensible.");
  148.  
  149. pointRc.Offset(0, pointRc.Height);
  150. addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-nodependences.png")),
  151. "No dependencies",
  152. "Generate and edit digital documents with no Acrobat or Excel dependencies.");
  153.  
  154. g.FillRectangle(new RectangleF(0, page.Size.Height - 16, page.Size.Width, 16), _darkGray);
  155.  
  156. drawCircle(new PointF(page.Size.Width - 160, backRcClip.Bottom - 105));
  157.  
  158. void addPoint(IImage img, string caption, string text)
  159. {
  160. var imgRc = new RectangleF(pointRc.X + 20, pointRc.Y + tl.MarginTop, 48, 48);
  161. g.DrawImage(img, imgRc, null, new ImageAlign() { AlignHorz = ImageAlignHorz.Center, AlignVert = ImageAlignVert.Center, BestFit = true });
  162. tl.Clear();
  163. tl.AppendLine(caption, new TextFormat() { FontName = "open sans semibold", FontSize = 11 });
  164. tl.Append(text, new TextFormat() { FontName = "open sans light", FontSize = 11 });
  165. tl.PerformLayout(true);
  166. if (!tl.ContentHeightFitsInBounds)
  167. throw new Exception("Unexpected: text overflow.");
  168. g.DrawTextLayout(tl, pointRc.Location);
  169. }
  170.  
  171. void drawCircle(PointF p)
  172. {
  173. float D = 128;
  174. float angle = (float)(16 * Math.PI) / 180f;
  175. g.Transform =
  176. Matrix3x2.CreateTranslation(-D / 2, -D / 2) *
  177. Matrix3x2.CreateRotation(angle) *
  178. Matrix3x2.CreateTranslation(p.X + D / 2, p.Y + D / 2);
  179.  
  180. var r = new RectangleF(PointF.Empty, new SizeF(D, D));
  181. for (int i = 0; i < 3; ++i)
  182. {
  183. g.FillEllipse(r, Color.FromArgb(30 + i * 10, _darkGray));
  184. r.Inflate(-1, -1);
  185. }
  186. g.FillEllipse(r, _darkGray);
  187. r.Inflate(-1, -1);
  188. g.FillEllipse(r, Color.White);
  189. r.Inflate(-6, -6);
  190. g.FillEllipse(r, _darkGray);
  191.  
  192. tl.Clear();
  193. tl.MaxHeight = tl.MaxWidth = D;
  194. tl.MarginLeft = tl.MarginRight = tl.MarginTop = tl.MarginBottom = 0;
  195. tl.TextAlignment = TextAlignment.Center;
  196. tl.ParagraphAlignment = ParagraphAlignment.Center;
  197. tl.ParagraphSpacing = -4;
  198. var tf = new TextFormat() { FontName = "open sans light", FontSize = 18, ForeColor = Color.White };
  199. tl.Append("DEPLOY\nTO", tf);
  200. tl.Append(" AZURE\n", new TextFormat(tf) { FontName = "open sans semibold" });
  201. tl.Append(" ");
  202. tl.PerformLayout(true);
  203. g.DrawTextLayout(tl, PointF.Empty);
  204.  
  205. g.Transform = Matrix3x2.Identity;
  206. }
  207. }
  208.  
  209. void Page2(GcPdfDocument doc)
  210. {
  211. var page = doc.Pages.Add();
  212. var g = page.Graphics;
  213. var tl = new TextLayout(g.Resolution) { FontCollection = _fc };
  214. var col0X = 36;
  215. var colWidth = page.Size.Width / 3 - 40;
  216. var colGap = 20;
  217. var vgap = 10;
  218. var ser1Y = 100;
  219. var ser2Y = 72 * 6;
  220. var h = 45;
  221.  
  222. List<(string caption, List<string> points)> dspdf = new List<(string, List<string>)>()
  223. {
  224. ("Advanced Text Handling", new List<string> {
  225. "Standard PDF Fonts, Truetype Fonts, Open type Fonts, WOFF Fonts, system font loading, font embedding, fallback and linked fonts, EUDC fonts",
  226. "Advanced text rendering features",
  227. "Special character support",
  228. }),
  229. ("Cross-Platform, Cross-Framework compatibility", new List<string>
  230. {
  231. ".NET Standard 2.0",
  232. ".NET Core 2.0",
  233. ".NET Framework",
  234. "Mono",
  235. "Xamarin iOS",
  236. "VSTO-style API"
  237. }),
  238. ("Security", new List<string>
  239. {
  240. "Encryption and decrpyption",
  241. "User and owner passwords",
  242. "AllowCopyContent, AllowEditAnnotations, AllowEditContent, AllowPrint",
  243. "Digital Signatures"
  244. }),
  245. ("Annotations", new List<string>
  246. {
  247. "Figures",
  248. "Comments",
  249. "Text",
  250. "Signatures",
  251. "Stamps",
  252. "Modify, extract or delete annotations from existing PDFs"
  253. }),
  254. ("Fillable Form Fields", new List<string>
  255. {
  256. "Textbox",
  257. "Checkbox",
  258. "Combobox",
  259. "Listbox",
  260. "Radio button",
  261. "Push button",
  262. "Signature field",
  263. "Modify, extract or delete form fields from existing PDFs"
  264. }),
  265. ("Navigation", new List<string>
  266. {
  267. "Outlines",
  268. "Hyperlinks"
  269. }),
  270. ("Additional Features", new List<string>
  271. {
  272. "50 barcodes and properties",
  273. "Create PDF/A files",
  274. "Maintain document history with document properties",
  275. "Generate linearized PDFs for fast web view",
  276. "Full image and graphic support on all platforms",
  277. "Add and delete pages",
  278. "Chage page sizes",
  279. "Page orientation"
  280. }),
  281. };
  282.  
  283. List<(string caption, List<string> points)> gcexcel = new List<(string, List<string>)>()
  284. {
  285. ("Fast and Efficient", new List<string>
  286. {
  287. "Lightweight",
  288. "Optimized for processing large Excel documents quickly"
  289. }),
  290. ("Cross-Platform, Cross-Framework compatibility", new List<string>
  291. {
  292. ".NET Standard 2.0",
  293. ".NET Core 2.0",
  294. ".NET Framework",
  295. "Mono",
  296. "Xamarin.iOS",
  297. "VSTO-style API",
  298. }),
  299. ("Data Visualization", new List<string>
  300. {
  301. "Shapes and pictures",
  302. "Slicers",
  303. "Sparklines",
  304. "Charts",
  305. }),
  306. ("Powerful Calculation Engine", new List<string>
  307. {
  308. "450+ Excel functions",
  309. "Calculate",
  310. "Query",
  311. "Generate",
  312. "Sorting",
  313. "Filtering",
  314. "Grouping",
  315. }),
  316. ("Seamless Excel Compatibility", new List<string>
  317. {
  318. "Import and export Excel files",
  319. "Export to PDF",
  320. "Encrypt files",
  321. "Workbooks and worksheets",
  322. "Cell range operations",
  323. "Pivot and Excel tables",
  324. "Data validation",
  325. "Annotations",
  326. "Comments",
  327. }),
  328. ("Conditional Formatting Rules", new List<string>
  329. {
  330. "Cell value",
  331. "Average",
  332. "Color scale",
  333. "Data bar",
  334. "Icon sets",
  335. "Top and Bottom",
  336. "Unique",
  337. "Expression",
  338. }),
  339. ("Flexible Themes And Components", new List<string>
  340. {
  341. "Customizable themes",
  342. "Configurable components",
  343. "Summary data",
  344. "Custom styles",
  345. "Embedded drawing objects",
  346. "Integrated calculation engine",
  347. }),
  348. };
  349.  
  350. addHeader(45,
  351. "Document Solutions for PDF",
  352. "This high-speed, feature-rich PDF document API for .NET Standard 2.0 gives you total " +
  353. "control of your PDF documents, with no dependencies on Adobe Acrobat.Generate, " +
  354. "edit, and store feature - rich PDF documents without compromising design or features.");
  355.  
  356. var ipt = new PointF(col0X, ser1Y);
  357. foreach (var (caption, points) in dspdf)
  358. {
  359. var rc = addList(ipt, caption, points.ToArray());
  360. if (rc.Bottom < ser2Y - 120)
  361. ipt = new PointF(rc.X, rc.Bottom + vgap);
  362. else
  363. ipt = new PointF(rc.X + colWidth + colGap, ser1Y);
  364. }
  365.  
  366. addHeader(ser2Y,
  367. "Document Solutions for Excel",
  368. "Generate high-performance Excel spreadsheets with no dependencies on Excel! " +
  369. "Generate, convert, calculate, format, and parse spreadsheets in any app.");
  370.  
  371. var topY = ser2Y + h + 10;
  372. ipt = new PointF(col0X, topY);
  373. foreach (var (caption, points) in gcexcel)
  374. {
  375. var rc = addList(ipt, caption, points.ToArray());
  376. if (rc.Bottom < page.Size.Height - 100)
  377. ipt = new PointF(rc.X, rc.Bottom + vgap);
  378. else
  379. ipt = new PointF(rc.X + colWidth + colGap, topY);
  380. }
  381.  
  382. var hdrRc = new RectangleF(28, 0, page.Size.Width - 28 * 2, 36);
  383. g.FillRectangle(hdrRc, _darkGray);
  384. var w = hdrRc.Width / 7;
  385. string[] hdrs = new string[] { "Create", "Load", "Edit", "Save", "Analyze" };
  386. var hdrTf = new TextFormat() { FontName = "open sans", FontSize = 12, ForeColor = Color.White };
  387. var trc = new RectangleF(hdrRc.X + w, hdrRc.Y, w, hdrRc.Height);
  388. for (int i = 0; i < hdrs.Length; ++i)
  389. {
  390. g.DrawString(hdrs[i], hdrTf, trc, TextAlignment.Center, ParagraphAlignment.Center, false);
  391. if (i < hdrs.Length - 1)
  392. g.DrawLine(trc.Right, trc.Top + 12, trc.Right, trc.Bottom - 12, Color.White, 1);
  393. trc.Offset(w, 0);
  394. }
  395. var ftrRc = new RectangleF(0, page.Size.Height - 36, page.Size.Width, 36);
  396. g.FillRectangle(ftrRc, _darkGray);
  397. var ftr0 = "mescius.com";
  398. var ftr1 = "© MESCIUS inc. All rights reserved. All other product and brand names are trademarks and/or registered trademarks of their respective holders.";
  399. ftrRc.Inflate(-col0X, -5);
  400. hdrTf.FontSize = 12;
  401. g.DrawString(ftr0, hdrTf, ftrRc, TextAlignment.Leading, ParagraphAlignment.Near, false);
  402. hdrTf.FontSize = 6;
  403. g.DrawString(ftr1, hdrTf, ftrRc, TextAlignment.Leading, ParagraphAlignment.Far, false);
  404. ftrRc.Inflate(0, -5);
  405. g.DrawImage(GetImage(Path.Combine("Resources", "ImagesBis", "logo-GC-white.png")), ftrRc, null,
  406. new ImageAlign() { AlignHorz = ImageAlignHorz.Right, AlignVert = ImageAlignVert.Center, BestFit = true });
  407.  
  408. void addHeader(float y, string caption, string text)
  409. {
  410. var bluerc = new RectangleF(0, y, 28, h);
  411. g.FillRectangle(bluerc, _blue);
  412. var caprc = new RectangleF(bluerc.Right, y, 72 * 2.75f, h);
  413. g.FillRectangle(caprc, _lightGray);
  414. caprc.X = col0X;
  415. caprc.Width -= col0X - bluerc.Width;
  416. g.DrawString(caption, new TextFormat() { FontName = "open sans semibold", FontSize = 12 }, caprc, TextAlignment.Leading, ParagraphAlignment.Center, false);
  417. var textrc = new RectangleF(caprc.Right, caprc.Top, page.Size.Width - caprc.Right, caprc.Height);
  418. textrc.Inflate(-10, 0);
  419. g.DrawString(text, new TextFormat() { FontName = "open sans light", FontSize = 9 }, textrc, TextAlignment.Leading, ParagraphAlignment.Center, true);
  420. }
  421.  
  422. RectangleF addList(PointF pt, string caption, params string[] items)
  423. {
  424. var tf = new TextFormat() { FontName = "open sans light", FontSize = 9 };
  425. var ret = new RectangleF(pt, SizeF.Empty);
  426. tl.Clear();
  427. tl.MaxWidth = colWidth;
  428. tl.AppendLine(caption, new TextFormat() { FontName = "open sans", FontBold = true, FontSize = 9 });
  429. tl.PerformLayout(true);
  430. g.DrawTextLayout(tl, pt);
  431. ret.Width = tl.ContentWidth;
  432. ret.Height = tl.ContentHeight;
  433. pt.Y += ret.Height;
  434. tl.Clear();
  435. var itemPrefix = "\u2022 ";
  436. tl.FirstLineIndent = -g.MeasureStringWithTrailingWhitespace(itemPrefix, tf).Width;
  437. foreach (var item in items)
  438. tl.AppendLine(itemPrefix + item, tf);
  439. tl.PerformLayout(true);
  440. g.DrawTextLayout(tl, pt);
  441. ret.Width = Math.Max(ret.Width, tl.ContentWidth);
  442. ret.Height += tl.ContentHeight;
  443. return ret;
  444. }
  445. }
  446. }
  447. }
  448.