GoodsReturnForm.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 GrapeCity.Documents.Common;
  9. using GrapeCity.Documents.Drawing;
  10. using GrapeCity.Documents.Pdf;
  11. using GrapeCity.Documents.Pdf.Annotations;
  12. using GrapeCity.Documents.Pdf.AcroForms;
  13. using GCTEXT = GrapeCity.Documents.Text;
  14. using GCDRAW = GrapeCity.Documents.Drawing;
  15.  
  16. namespace DsPdfWeb.Demos.OrderReturnForm
  17. {
  18. // Creates a "Goods return or exchange form" AcroForm with multiple input fields and a complex layout.
  19. public class GoodsReturnForm
  20. {
  21. // Page margins:
  22. const float MarginLeft = 32;
  23. const float MarginTop = 32;
  24. const float MarginRight = 32;
  25. const float MarginBottom = 32;
  26. //
  27. const float TableCaptionHeight = 20;
  28. readonly float TableSampleHeight = Textbox.Height;
  29. const float SmallTextVOff = -0.5f;
  30. // Section delimiting line:
  31. float CaptionLineThickness = 2.5f;
  32. // Struct to hold a text style:
  33. struct TextStyle
  34. {
  35. public GCTEXT.Font Font;
  36. public float FontSize;
  37. public Color ForeColor;
  38. public float GlyphAdvanceFactor;
  39. }
  40. // Various styles used throughout the form:
  41. static TextStyle TsTitle = new TextStyle()
  42. {
  43. Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "SitkaB.ttc")),
  44. FontSize = 30,
  45. ForeColor = Color.FromArgb(0xff, 0x3b, 0x5c, 0xaa),
  46. GlyphAdvanceFactor = 0.93f,
  47. };
  48. static TextStyle TsCaption = new TextStyle()
  49. {
  50. Font = TsTitle.Font,
  51. FontSize = 14,
  52. ForeColor = Color.FromArgb(0xff, 0x3b, 0x5c, 0xaa),
  53. GlyphAdvanceFactor = 0.93f,
  54. };
  55. static TextStyle TsBold = new TextStyle()
  56. {
  57. Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arialbd.ttf")),
  58. FontSize = 9,
  59. ForeColor = Color.Black,
  60. GlyphAdvanceFactor = 1,
  61. };
  62. static TextStyle TsNormal = new TextStyle()
  63. {
  64. Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arial.ttf")),
  65. FontSize = 8f,
  66. ForeColor = Color.Black,
  67. GlyphAdvanceFactor = 0.922f,
  68. };
  69. static TextStyle TsSmall = new TextStyle()
  70. {
  71. Font = TsNormal.Font,
  72. FontSize = 5,
  73. ForeColor = Color.FromArgb(0x0F, 0x0F, 0x0F),
  74. GlyphAdvanceFactor = 1.1f,
  75. };
  76. // Input field styles:
  77. struct Textbox
  78. {
  79. static public GCTEXT.Font Font = TsNormal.Font;
  80. static public float FontSize = 12;
  81. static public float Height;
  82. static public float BaselineOffset;
  83. static public float LabelSpacing = 2;
  84. }
  85. struct Checkbox
  86. {
  87. static public GCTEXT.Font Font = TsNormal.Font;
  88. static public float FontSize = TsNormal.FontSize - 2;
  89. static public float Height;
  90. static public float BaselineOffset;
  91. static public float LabelSpacing = 3;
  92. }
  93. // The document being created:
  94. private GcPdfDocument _doc;
  95. // Insertion point:
  96. private PointF _ip = new PointF(MarginLeft, MarginTop);
  97. // If non-null, DrawText use this to align text to last baseline:
  98. private float? _lastBaselineOffset = null;
  99. // Shortcuts to current values:
  100. private int CurrPageIdx => _doc.Pages.Count - 1;
  101. private Page CurrPage => _doc.Pages[CurrPageIdx];
  102. private GcGraphics CurrGraphics => CurrPage.Graphics;
  103.  
  104. // Static ctor:
  105. static GoodsReturnForm()
  106. {
  107. // Init Textbox:
  108. GCTEXT.TextLayout tl = new GCTEXT.TextLayout(72);
  109. tl.Append("Qwerty");
  110. tl.DefaultFormat.Font = Textbox.Font;
  111. tl.DefaultFormat.FontSize = Textbox.FontSize;
  112. tl.PerformLayout(true);
  113. Textbox.Height = tl.ContentHeight;
  114. Textbox.BaselineOffset = tl.Lines[0].GlyphRuns[0].BaselineOffset;
  115. // Init Checkbox:
  116. tl.Clear();
  117. tl.Append("Qwerty");
  118. tl.DefaultFormat.Font = Checkbox.Font;
  119. tl.DefaultFormat.FontSize = Checkbox.FontSize;
  120. tl.PerformLayout(true);
  121. Checkbox.Height = tl.ContentHeight;
  122. Checkbox.BaselineOffset = tl.Lines[0].GlyphRuns[0].BaselineOffset;
  123. }
  124.  
  125. // The main entry point:
  126. public int CreatePDF(Stream stream)
  127. {
  128. Acme();
  129. _doc.Save(stream);
  130. return _doc.Pages.Count;
  131. }
  132.  
  133. // Sets or advances the insertion point vertically:
  134. private void SetY(float? abs, float? offset)
  135. {
  136. if (abs.HasValue)
  137. _ip.Y = abs.Value;
  138. if (offset.HasValue)
  139. _ip.Y += offset.Value;
  140. _lastBaselineOffset = null;
  141. }
  142.  
  143. // Creates the PDF form:
  144. private void Acme()
  145. {
  146. _doc = new GcPdfDocument();
  147. _doc.NewPage();
  148. var pageWidth = CurrPage.Size.Width;
  149.  
  150. // Main caption:
  151. SetY(null, -2);
  152. var cr = DrawText("ACME Inc.", TsTitle);
  153. SetY(null, _lastBaselineOffset - CaptionLineThickness / 2);
  154. DrawGreenLine(MarginLeft, cr.Left - CaptionLineThickness);
  155. DrawGreenLine(cr.Right + CaptionLineThickness, pageWidth - MarginRight);
  156.  
  157. // 'return and exchange form':
  158. SetY(cr.Bottom, 10);
  159. cr = DrawText("Return and Exchange Form", TsCaption);
  160.  
  161. SetY(null, CaptionLineThickness + 14);
  162. cr = DrawText("Please type in the appropriate information below, then print this form.", TsBold);
  163. _ip.X = pageWidth - 150;
  164. cr = DrawText("Have Any Questions?", TsBold);
  165.  
  166. SetY(null, 10);
  167. _ip.X = MarginLeft;
  168. cr = DrawText("(Or you may print the form and complete it by hand.)", TsNormal);
  169. _ip.X = pageWidth - 150;
  170. cr = DrawText("Please call us at 800-123-4567.", TsNormal);
  171.  
  172. // Step 1 - line 1:
  173. SetY(null, 18);
  174. _ip.X = MarginLeft;
  175. cr = DrawText("Step 1", TsCaption);
  176. _ip.X = cr.Right + 10;
  177. cr = DrawText("Original Order #", TsBold);
  178. _ip.X = cr.Right + 4;
  179. cr = DrawText("(if available):", TsNormal);
  180. _ip.X = cr.Right + Textbox.LabelSpacing;
  181. cr = DrawTextbox(120);
  182. _ip.X = cr.Right + 6;
  183. cr = DrawText("Estimated Order Date:", TsBold);
  184. _ip.X = cr.Right + Textbox.LabelSpacing;
  185. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  186. SetY(null, 17);
  187. DrawGreenLine();
  188. // Step 1 - line 2:
  189. SetY(null, 10);
  190. _ip.X = MarginLeft;
  191. cr = DrawText("Originally Purchased by:", TsBold);
  192. _ip.X = cr.Right + 20;
  193. cr = DrawCheckbox("Address Change");
  194. float col1right = pageWidth / 2 - 10;
  195. float col2left = col1right + 20;
  196. _ip.X = col2left;
  197. cr = DrawText("Send Refund or Exchange to:", TsBold);
  198. _ip.X = cr.Right + 2;
  199. cr = DrawText("(If different from left)", TsNormal);
  200. // Step 1 - line 3:
  201. SetY(cr.Bottom, 10);
  202. _ip.X = MarginLeft;
  203. cr = DrawText("Name:", TsNormal);
  204. _ip.X = cr.Right + Textbox.LabelSpacing;
  205. cr = DrawTextbox(col1right - _ip.X);
  206. _ip.X = col2left;
  207. cr = DrawText("Name:", TsNormal);
  208. _ip.X = cr.Right + Textbox.LabelSpacing;
  209. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  210. // Step 1 - line 4:
  211. SetY(cr.Bottom, 4 + 4);
  212. _ip.X = MarginLeft;
  213. cr = DrawText("Address:", TsNormal);
  214. _ip.X = cr.Right + Textbox.LabelSpacing;
  215. cr = DrawTextbox(col1right - _ip.X);
  216. _ip.X = col2left;
  217. cr = DrawText("Address:", TsNormal);
  218. _ip.X = cr.Right + Textbox.LabelSpacing;
  219. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  220. // Step 1 - line 5:
  221. SetY(cr.Bottom, 4 + 0.5f);
  222. _ip.X = MarginLeft;
  223. cr = DrawTextbox(col1right - _ip.X);
  224. _ip.X = col2left;
  225. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  226. // Step 1 - line 6 (city state zip):
  227. SetY(cr.Bottom, 4 + 0.5f);
  228. _ip.X = MarginLeft;
  229. cr = DrawTextbox(160);
  230. _ip.X = cr.Right + 4;
  231. float oState = _ip.X - MarginLeft;
  232. cr = DrawTextbox(40);
  233. _ip.X = cr.Right + 4;
  234. float oZip = _ip.X - MarginLeft;
  235. cr = DrawTextbox(col1right - _ip.X);
  236. //
  237. _ip.X = col2left;
  238. cr = DrawTextbox(160);
  239. _ip.X = cr.Right + 4;
  240. cr = DrawTextbox(40);
  241. _ip.X = cr.Right + 4;
  242. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  243. // small text
  244. SetY(cr.Bottom, SmallTextVOff);
  245. _ip.X = MarginLeft;
  246. cr = DrawText("(City)", TsSmall);
  247. _ip.X = MarginLeft + oState;
  248. cr = DrawText("(State)", TsSmall);
  249. _ip.X = MarginLeft + oZip;
  250. cr = DrawText("(Zip)", TsSmall);
  251. //
  252. _ip.X = col2left;
  253. cr = DrawText("(City)", TsSmall);
  254. _ip.X = col2left + oState;
  255. cr = DrawText("(State)", TsSmall);
  256. _ip.X = col2left + oZip;
  257. cr = DrawText("(Zip)", TsSmall);
  258. // Step 1 - line 7 (daytime):
  259. SetY(cr.Bottom, 4 - 0.5f);
  260. _ip.X = MarginLeft;
  261. cr = DrawText("Phone: (", TsNormal);
  262. _ip.X = cr.Right;
  263. cr = DrawTextbox(30);
  264. _ip.X = cr.Right;
  265. cr = DrawText(")", TsNormal);
  266. _ip.X += 3;
  267. cr = DrawTextbox(80);
  268. float oDay = cr.Left - MarginLeft + 10;
  269. // (evening)
  270. _ip.X = cr.Right + 3;
  271. cr = DrawText("(", TsNormal);
  272. _ip.X = cr.Right;
  273. cr = DrawTextbox(30);
  274. _ip.X = cr.Right;
  275. cr = DrawText(")", TsNormal);
  276. _ip.X += 3;
  277. cr = DrawTextbox(col1right - _ip.X);
  278. float oEve = cr.Left - MarginLeft + 10;
  279. //
  280. _ip.X = col2left;
  281. cr = DrawText("Phone: (", TsNormal);
  282. _ip.X = cr.Right;
  283. cr = DrawTextbox(30);
  284. _ip.X = cr.Right;
  285. cr = DrawText(")", TsNormal);
  286. _ip.X += 3;
  287. cr = DrawTextbox(80);
  288. // (evening)
  289. _ip.X = cr.Right + 3;
  290. cr = DrawText("(", TsNormal);
  291. _ip.X = cr.Right;
  292. cr = DrawTextbox(30);
  293. _ip.X = cr.Right;
  294. cr = DrawText(")", TsNormal);
  295. _ip.X += 3;
  296. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  297. // small text
  298. SetY(cr.Bottom, SmallTextVOff);
  299. _ip.X = MarginLeft + oDay;
  300. cr = DrawText("(Daytime)", TsSmall);
  301. _ip.X = MarginLeft + oEve;
  302. cr = DrawText("(Evening)", TsSmall);
  303. _ip.X = col2left + oDay;
  304. cr = DrawText("(Daytime)", TsSmall);
  305. _ip.X = col2left + oEve;
  306. cr = DrawText("(Evening)", TsSmall);
  307. // Step 1 - email
  308. SetY(cr.Bottom, 4 - 0.5f);
  309. _ip.X = MarginLeft;
  310. cr = DrawText("Email Address:", TsNormal);
  311. _ip.X = cr.Right + Textbox.LabelSpacing;
  312. cr = DrawTextbox(col1right - _ip.X);
  313. _ip.X = col2left;
  314. cr = DrawText("Email Address:", TsNormal);
  315. _ip.X = cr.Right + Textbox.LabelSpacing;
  316. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  317. // Options:
  318. SetY(null, 16);
  319. _ip.X = MarginLeft;
  320. cr = DrawText("Please select one of the following options:", TsBold);
  321. SetY(cr.Bottom, 2);
  322. cr = DrawCheckbox("Exchange for another item(s).");
  323. SetY(cr.Bottom, 2);
  324. cr = DrawCheckbox("Send me an ACME Gift Card for the amount of the refund.");
  325. SetY(cr.Bottom, 2);
  326. cr = DrawCheckbox("Reimburse my original method of payment. " +
  327. "(Gift recipients who select this option will receive a merchandise only gift card.)");
  328.  
  329. // Step 2:
  330. SetY(null, 18);
  331. _ip.X = MarginLeft;
  332. cr = DrawText("Step 2–Returns", TsCaption);
  333. _ip.X = cr.Right + 10;
  334. cr = DrawText("In the form below please indicate the item(s) you are returning, " +
  335. "including a reason code.", TsNormal);
  336. SetY(null, 17);
  337. DrawGreenLine();
  338. SetY(null, 10);
  339. cr = DrawReturnsTable();
  340. SetY(cr.Bottom, 10);
  341. cr = DrawReasonCodes();
  342.  
  343. // Step 3:
  344. SetY(null, 25);
  345. _ip.X = MarginLeft;
  346. cr = DrawText("Step 3–Exchanges", TsCaption);
  347. _ip.X = cr.Right + 10;
  348. SetY(null, -5);
  349. cr = DrawText(
  350. "For the fastest service, call Customer Service at 800-123-4567 to request a QuickExchange " +
  351. "or place a new order online or by phone. We'll ship your new item right away. " +
  352. "Note: If you use our QuickExchange option, you do not need to fill out Step 3.",
  353. TsNormal);
  354. SetY(null, 22);
  355. DrawGreenLine();
  356.  
  357. SetY(null, 10);
  358. cr = DrawExchangesTable();
  359.  
  360. // Step 4:
  361. SetY(null, 18);
  362. _ip.X = MarginLeft;
  363. cr = DrawText("Step 4", TsCaption);
  364. SetY(null, 17);
  365. DrawGreenLine();
  366.  
  367. SetY(null, 10);
  368. _ip.X = MarginLeft;
  369. float oCc = col2left - 30;
  370. cr = DrawText("Method of Payment:", TsBold);
  371. _ip.X = oCc;
  372. cr = DrawText("Credit Card Information:", TsBold);
  373. SetY(cr.Bottom, 2);
  374. _ip.X = MarginLeft;
  375. cr = DrawText("If the total of your exchange or new order exceeds the value of your\r\n" +
  376. "return, please provide a method of payment. (Select one)", TsNormal);
  377. _ip.X = oCc;
  378. cr = DrawCheckbox("ACME® Visa®");
  379. float oCcOff = 90;
  380. _ip.X += oCcOff;
  381. cr = DrawCheckbox("MasterCard®");
  382. _ip.X += oCcOff;
  383. cr = DrawCheckbox("JCB Cardâ„¢");
  384.  
  385. SetY(cr.Bottom, 2);
  386. _ip.X = oCc;
  387. cr = DrawCheckbox("VISA");
  388. _ip.X += oCcOff;
  389. cr = DrawCheckbox("American Express");
  390. _ip.X += oCcOff;
  391. cr = DrawCheckbox("Discover®/Novus® Cards");
  392.  
  393. SetY(cr.Bottom, 4);
  394. _ip.X = MarginLeft;
  395. cr = DrawCheckbox("Credit Card");
  396. SetY(cr.Bottom, 2);
  397. cr = DrawCheckbox("Check or Money Order enclosed");
  398. SetY(cr.Bottom, 2);
  399. cr = DrawCheckbox("Gift Card, Gift Certificate or ACME Visa coupon dollars.\r\n" +
  400. "Enter # below (for Gift Cards, please include PIN).");
  401.  
  402. _ip.X = oCc;
  403. cr = DrawText("Card Number:", TsNormal);
  404. _ip.X = cr.Right + Textbox.LabelSpacing;
  405. cr = DrawTextbox(180);
  406. _ip.X = cr.Right + 4;
  407. cr = DrawTextbox(pageWidth - MarginRight - _ip.X);
  408. // small text
  409. SetY(cr.Bottom, SmallTextVOff);
  410. _ip.X = cr.Left;
  411. cr = DrawText("Exp. Date (MM/YY)", TsSmall);
  412.  
  413. SetY(cr.Bottom, 10);
  414. _ip.X = MarginLeft;
  415. cr = DrawText("Number:", TsNormal);
  416. _ip.X = cr.Right + Textbox.LabelSpacing;
  417. cr = DrawTextbox(140);
  418. float tbBottom = cr.Bottom;
  419. _ip.X = cr.Right + 4;
  420. cr = DrawTextbox(60);
  421. float oPin = cr.Left;
  422. _ip.X = oCc;
  423. cr = DrawText("Signature:", TsNormal);
  424. CurrGraphics.DrawLine(new PointF(cr.Right, cr.Bottom),
  425. new PointF(pageWidth - MarginRight, cr.Bottom), Color.Black, 0.5f);
  426. // small text
  427. SetY(tbBottom, SmallTextVOff);
  428. _ip.X = oPin;
  429. cr = DrawText("PIN", TsSmall);
  430. }
  431.  
  432. private void DrawGreenLine(float? from = null, float? to = null)
  433. {
  434. var page = CurrPage;
  435. if (!from.HasValue)
  436. from = MarginLeft;
  437. if (!to.HasValue)
  438. to = page.Size.Width - MarginRight;
  439. var g = page.Graphics;
  440. var pen = new GCDRAW.Pen(TsTitle.ForeColor, CaptionLineThickness);
  441. g.DrawLine(new PointF(from.Value, _ip.Y), new PointF(to.Value, _ip.Y), pen);
  442. }
  443.  
  444. private RectangleF DrawText(string text, TextStyle ts)
  445. {
  446. var page = CurrPage;
  447. GCTEXT.TextLayout tl = page.Graphics.CreateTextLayout();
  448. tl.MaxWidth = page.Size.Width - MarginRight - _ip.X;
  449. if (ts.FontSize == TsTitle.FontSize) // patch
  450. tl.TextAlignment = GCTEXT.TextAlignment.Center;
  451. tl.DefaultFormat.Font = ts.Font;
  452. tl.DefaultFormat.FontSize = ts.FontSize;
  453. tl.DefaultFormat.GlyphAdvanceFactor = ts.GlyphAdvanceFactor;
  454. tl.DefaultFormat.ForeColor = ts.ForeColor;
  455. tl.Append(text);
  456. tl.PerformLayout(true);
  457.  
  458. var line = tl.Lines[tl.Lines.Count - 1];
  459. var run = line.GlyphRuns[0];
  460. var baselineOffset = run.BaselineOffset;
  461.  
  462. var p = _lastBaselineOffset.HasValue ?
  463. new PointF(_ip.X, _ip.Y + _lastBaselineOffset.Value - baselineOffset) : _ip;
  464. page.Graphics.DrawTextLayout(tl, p);
  465. if (!_lastBaselineOffset.HasValue)
  466. _lastBaselineOffset = baselineOffset; //#34 within one 'line', keep using the first offset
  467.  
  468. return new RectangleF(_ip.X + tl.ContentX, _ip.Y + tl.ContentY, tl.ContentWidth, tl.ContentHeight);
  469. }
  470.  
  471. private RectangleF DrawTextbox(float width, bool inTable = false)
  472. {
  473. var fld = new TextField();
  474. fld.Widget.Page = CurrPage;
  475. var p = _lastBaselineOffset.HasValue ?
  476. new PointF(_ip.X, _ip.Y + _lastBaselineOffset.Value - Textbox.BaselineOffset) : _ip;
  477. fld.Widget.Rect = new RectangleF(p.X, p.Y, width, Textbox.Height);
  478. if (inTable)
  479. fld.Widget.Border = null;
  480. else
  481. fld.Widget.Border.Style = BorderStyle.Underline;
  482. fld.Widget.DefaultAppearance.Font = Textbox.Font;
  483. fld.Widget.DefaultAppearance.FontSize = Textbox.FontSize;
  484. _doc.AcroForm.Fields.Add(fld);
  485. if (!_lastBaselineOffset.HasValue)
  486. _lastBaselineOffset = Textbox.BaselineOffset;
  487. return fld.Widget.Rect;
  488. }
  489.  
  490. private RectangleF DrawCheckbox(string text)
  491. {
  492. var fld = new CheckBoxField();
  493. fld.Widget.Page = CurrPage;
  494. var p = _lastBaselineOffset.HasValue ?
  495. new PointF(_ip.X, _ip.Y + _lastBaselineOffset.Value - Checkbox.BaselineOffset) : _ip;
  496. fld.Widget.Rect = new RectangleF(p.X, p.Y, Checkbox.Height, Checkbox.Height);
  497. _doc.AcroForm.Fields.Add(fld);
  498. if (!_lastBaselineOffset.HasValue)
  499. _lastBaselineOffset = Checkbox.BaselineOffset;
  500. var pSave = _ip;
  501. _ip.X = fld.Widget.Rect.Right + Checkbox.LabelSpacing;
  502. var r = DrawText(text, TsNormal);
  503. _ip = pSave;
  504. return new RectangleF(fld.Widget.Rect.X, r.Y, r.Right - fld.Widget.Rect.Left, r.Height);
  505. }
  506.  
  507. private RectangleF DrawReturnsTable()
  508. {
  509. float[] widths = new float[]
  510. {
  511. 55,
  512. 60,
  513. 60,
  514. 35,
  515. 35,
  516. 200,
  517. 50,
  518. 0
  519. };
  520. string[] captions = new string[]
  521. {
  522. "Reason Code",
  523. "Item #",
  524. "Color",
  525. "Size",
  526. "Quantity",
  527. "Item Name",
  528. "Pirce",
  529. "Total",
  530. };
  531. string[] samples = new string[]
  532. {
  533. "23",
  534. "KK123456",
  535. "Navy",
  536. "8",
  537. "1",
  538. "Example Item Only",
  539. "59.00",
  540. "59.00",
  541. };
  542.  
  543. return DrawTable(widths, captions, samples, 4);
  544. }
  545.  
  546. private RectangleF DrawExchangesTable()
  547. {
  548. // This table has two special extra titles spanning two tolumns.
  549. // To achieve this, we:
  550. // - force the column titles in those 4 columns to print as '2nd paragraph',
  551. // thus leaving an empty line for the span title;
  552. // - print the span titles here as a special case.
  553. float[] widths = new float[]
  554. {
  555. 50,
  556. 25,
  557. 25,
  558. 25,
  559. 25,
  560. 60,
  561. 150,
  562. 50,
  563. 40,
  564. 25,
  565. 35,
  566. 0
  567. };
  568. string[] captions = new string[]
  569. {
  570. "Item",
  571. "Style",
  572. "\r\n1st",
  573. "\r\n2nd",
  574. "Size",
  575. "Sleeve Length\r\n& Inseam",
  576. "Item Name",
  577. "\r\nCharacters",
  578. "\r\nStyle",
  579. "Qty.",
  580. "Price",
  581. "Total"
  582. };
  583. string[] samples = new string[]
  584. {
  585. "LH123456",
  586. "Plain",
  587. "Tan",
  588. "Olive",
  589. "8",
  590. "28",
  591. "Example Item Only",
  592. "Amanda",
  593. "Block",
  594. "1",
  595. "49.95",
  596. "49.95"
  597. };
  598.  
  599. var cr = DrawTable(widths, captions, samples, 4);
  600.  
  601. // print 2 spanning titles:
  602. var g = CurrGraphics;
  603. GCTEXT.TextLayout tl = g.CreateTextLayout();
  604. tl.ParagraphAlignment = GCTEXT.ParagraphAlignment.Near;
  605. tl.TextAlignment = GCTEXT.TextAlignment.Center;
  606. tl.DefaultFormat.Font = TsNormal.Font;
  607. tl.DefaultFormat.FontSize = TsNormal.FontSize;
  608. tl.DefaultFormat.GlyphAdvanceFactor = TsNormal.GlyphAdvanceFactor;
  609. tl.DefaultFormat.ForeColor = Color.White;
  610. tl.WrapMode = GCTEXT.WrapMode.NoWrap;
  611. // Color Choice
  612. var width = widths[2] + widths[3];
  613. tl.MaxWidth = width;
  614. tl.Append("Color Choice");
  615. tl.PerformLayout(true);
  616. var pt = new PointF(cr.Left + widths[0] + widths[1], cr.Top);
  617. g.DrawTextLayout(tl, pt);
  618. var pen = new GCDRAW.Pen(Color.White, 0.5f);
  619. var pt1 = new PointF(pt.X + 0.5f, pt.Y + TableCaptionHeight / 2);
  620. var pt2 = new PointF(pt1.X + width, pt1.Y);
  621. g.DrawLine(pt1, pt2, pen);
  622. pt1 = new PointF(pt.X + widths[2] + 0.5f, pt.Y + TableCaptionHeight / 2);
  623. pt2 = new PointF(pt1.X, pt.Y + TableCaptionHeight);
  624. g.DrawLine(pt1, pt2, pen);
  625. pt1 = new PointF(pt.X + 0.5f, pt.Y);
  626. pt2 = new PointF(pt1.X, pt.Y + TableCaptionHeight);
  627. g.DrawLine(pt1, pt2, pen);
  628. pt1 = new PointF(pt.X + width + 0.5f, pt.Y);
  629. pt2 = new PointF(pt1.X, pt.Y + TableCaptionHeight);
  630. g.DrawLine(pt1, pt2, pen);
  631.  
  632. // Monogramming
  633. width = widths[7] + widths[8];
  634. tl.Inlines.Clear();
  635. tl.MaxWidth = width;
  636. tl.Append("Monogramming");
  637. tl.PerformLayout(true);
  638. pt = new PointF(cr.Left + widths[0] + widths[1] + widths[2] + widths[3] + widths[4] + widths[5] + widths[6], cr.Top);
  639. g.DrawTextLayout(tl, pt);
  640. pt1 = new PointF(pt.X + 0.5f, pt.Y + TableCaptionHeight / 2);
  641. pt2 = new PointF(pt1.X + width, pt1.Y);
  642. g.DrawLine(pt1, pt2, pen);
  643. pt1 = new PointF(pt.X + widths[7] + 0.5f, pt.Y + TableCaptionHeight / 2);
  644. pt2 = new PointF(pt1.X, pt.Y + TableCaptionHeight);
  645. g.DrawLine(pt1, pt2, pen);
  646. pt1 = new PointF(pt.X + 0.5f, pt.Y);
  647. pt2 = new PointF(pt1.X, pt.Y + TableCaptionHeight);
  648. g.DrawLine(pt1, pt2, pen);
  649. pt1 = new PointF(pt.X + width + 0.5f, pt.Y);
  650. pt2 = new PointF(pt1.X, pt.Y + TableCaptionHeight);
  651. g.DrawLine(pt1, pt2, pen);
  652.  
  653. return cr;
  654. }
  655.  
  656. private RectangleF DrawTable(float[] widths, string[] captions, string[] samples, int rowCount)
  657. {
  658. System.Diagnostics.Debug.Assert(captions.Length == widths.Length && samples.Length == widths.Length);
  659.  
  660. var ipSave = _ip;
  661. var p = new GCDRAW.Pen(Color.Black, 0.5f);
  662.  
  663. var g = CurrGraphics;
  664. GCTEXT.TextLayout tl = g.CreateTextLayout();
  665. tl.ParagraphAlignment = GCTEXT.ParagraphAlignment.Center;
  666. tl.TextAlignment = GCTEXT.TextAlignment.Center;
  667. tl.DefaultFormat.Font = TsNormal.Font;
  668. tl.DefaultFormat.FontSize = TsNormal.FontSize;
  669. tl.DefaultFormat.GlyphAdvanceFactor = TsNormal.GlyphAdvanceFactor;
  670. tl.DefaultFormat.ForeColor = Color.White;
  671. tl.WrapMode = GCTEXT.WrapMode.NoWrap;
  672. tl.MaxHeight = TableCaptionHeight;
  673. float totW = 0;
  674. for (int i = 0; i < widths.Length; ++i)
  675. {
  676. if (i == widths.Length - 1)
  677. {
  678. widths[i] = CurrPage.Size.Width - MarginLeft - MarginRight - totW - 1;
  679. totW += 1;
  680. }
  681. totW += widths[i];
  682. }
  683. g.FillRectangle(new RectangleF(MarginLeft, _ip.Y, totW, TableCaptionHeight), Color.Black);
  684. var pt = new PointF(MarginLeft, _ip.Y);
  685. for (int i = 0; i < widths.Length; ++i)
  686. {
  687. tl.MaxWidth = widths[i];
  688. tl.Append(captions[i]);
  689. tl.PerformLayout(true);
  690. g.DrawTextLayout(tl, pt);
  691. pt.X = pt.X + widths[i];
  692. tl.Inlines.Clear();
  693. }
  694. tl.DefaultFormat.ForeColor = Color.Teal;
  695. tl.MaxHeight = TableSampleHeight;
  696. pt = new PointF(MarginLeft, _ip.Y + TableCaptionHeight);
  697. for (int i = 0; i < widths.Length; ++i)
  698. {
  699. tl.MaxWidth = widths[i];
  700. tl.Append(samples[i]);
  701. tl.PerformLayout(true);
  702. g.DrawTextLayout(tl, pt);
  703. pt.X = pt.X + widths[i];
  704. tl.Inlines.Clear();
  705. }
  706. SetY(_ip.Y + TableCaptionHeight + TableSampleHeight, 0.5f);
  707. for (int row = 0; row < rowCount; ++row)
  708. {
  709. _ip.X = MarginLeft + 1;
  710. for (int i = 0; i < widths.Length; ++i)
  711. {
  712. var cr = DrawTextbox(widths[i] - 1, true);
  713. _ip.X = cr.Right + 1;
  714. }
  715. g.DrawLine(new PointF(MarginLeft, _ip.Y - 0.5f), new PointF(MarginLeft + totW, _ip.Y - 0.5f), p);
  716. SetY(null, Textbox.Height + 1);
  717. }
  718. var totH = TableCaptionHeight + TableSampleHeight + (Textbox.Height + 1) * rowCount;
  719. _ip.X = MarginLeft + 0.5f;
  720. for (int i = 0; i < widths.Length - 1; ++i)
  721. {
  722. _ip.X += widths[i];
  723. g.DrawLine(new PointF(_ip.X, ipSave.Y), new PointF(_ip.X, ipSave.Y + totH), p);
  724. }
  725.  
  726. var rect = new RectangleF(MarginLeft, ipSave.Y, totW, totH);
  727. g.DrawRectangle(rect, p);
  728.  
  729. return rect;
  730. }
  731.  
  732. private RectangleF DrawReasonCodes()
  733. {
  734. float startX = 150;
  735. float capOff = 16;
  736. float colOff = 110;
  737. var ipSave = _ip;
  738.  
  739. _ip.X = startX;
  740. var cr = DrawText("01", TsNormal);
  741. _ip.X += capOff;
  742. cr = DrawText("Unsatisfactory", TsNormal);
  743. _ip.X = startX + colOff;
  744. cr = DrawText("33", TsNormal);
  745. _ip.X += capOff;
  746. cr = DrawText("Did not like color", TsNormal);
  747. _ip.X = startX + colOff * 2;
  748. cr = DrawText("23", TsNormal);
  749. _ip.X += capOff;
  750. cr = DrawText("Ordered wrong size", TsNormal);
  751. _ip.X = startX + colOff * 3;
  752. cr = DrawText("51", TsNormal);
  753. _ip.X += capOff;
  754. cr = DrawText("Shipping damage", TsNormal);
  755. SetY(null, TsNormal.FontSize + 2);
  756. _ip.X = startX;
  757. cr = DrawText("02", TsNormal);
  758. _ip.X += capOff;
  759. cr = DrawText("Defective construction", TsNormal);
  760. _ip.X = startX + colOff;
  761. cr = DrawText("21", TsNormal);
  762. _ip.X += capOff;
  763. cr = DrawText("Too small", TsNormal);
  764. _ip.X = startX + colOff * 2;
  765. cr = DrawText("25", TsNormal);
  766. _ip.X += capOff;
  767. cr = DrawText("Too short", TsNormal);
  768. _ip.X = startX + colOff * 3;
  769. cr = DrawText("52", TsNormal);
  770. _ip.X += capOff;
  771. cr = DrawText("Wrong item shipped", TsNormal);
  772.  
  773. _ip.X = MarginLeft + 10;
  774. cr = DrawText("Reason Codes", TsBold);
  775. float lineX = cr.Right + 20;
  776.  
  777. SetY(null, TsNormal.FontSize + 2);
  778. _ip.X = startX;
  779. cr = DrawText("31", TsNormal);
  780. _ip.X += capOff;
  781. cr = DrawText("Did not like styling", TsNormal);
  782. _ip.X = startX + colOff;
  783. cr = DrawText("22", TsNormal);
  784. _ip.X += capOff;
  785. cr = DrawText("Too large", TsNormal);
  786. _ip.X = startX + colOff * 2;
  787. cr = DrawText("36", TsNormal);
  788. _ip.X += capOff;
  789. cr = DrawText("Too long", TsNormal);
  790.  
  791. var rect = new RectangleF(MarginLeft, ipSave.Y, CurrPage.Size.Width, cr.Bottom - ipSave.Y);
  792. CurrGraphics.DrawLine(lineX, rect.Top, lineX, rect.Bottom, Color.Black, 0.5f);
  793.  
  794. return rect;
  795. }
  796. }
  797. }
  798.