NumberedList.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.Pdf;
  9. using GrapeCity.Documents.Text;
  10. using GrapeCity.Documents.Drawing;
  11.  
  12. namespace DsPdfWeb.Demos.Basics
  13. {
  14. // Demonstrates how paragraphs of text can be rendered as a numbered list in DsPdf.
  15. // The method of rendering pages of text in this sample is taken from the PaginatedText
  16. // sample. See also TextRendering.
  17. public class NumberedList
  18. {
  19. // Encapsulate page layout constants used in the sample:
  20. private struct Layout
  21. {
  22. public static float Margin => 72;
  23. public static float ListOffset => 24;
  24. };
  25.  
  26. // Utility method which pre-pends numbers to all paragraphs in a TextLayout.
  27. private void AddBullets(GcGraphics g, PointF pt, TextLayout tl, ref int itemNo)
  28. {
  29. var tlBullet = g.CreateTextLayout();
  30. tlBullet.DefaultFormat.Font = StandardFonts.Times;
  31. tlBullet.DefaultFormat.FontSize = 12;
  32. foreach (var line in tl.Lines)
  33. {
  34. if (line.FirstLineInParagraph)
  35. {
  36. tlBullet.Clear();
  37. tlBullet.Append($"{itemNo++})");
  38. tlBullet.PerformLayout(true);
  39. g.DrawTextLayout(tlBullet, new PointF(pt.X, pt.Y + line.Position + line.LineGap));
  40. }
  41. }
  42. }
  43.  
  44. // Main entry point:
  45. public int CreatePDF(Stream stream)
  46. {
  47. var doc = new GcPdfDocument();
  48. var ip = new PointF(Layout.Margin, Layout.Margin);
  49. // Use TextLayout.MarginLeft to reserve space for list numbers/bullets:
  50. var tl = new TextLayout(72)
  51. {
  52. MaxWidth = doc.PageSize.Width - Layout.Margin * 2,
  53. MaxHeight = doc.PageSize.Height - Layout.Margin * 2,
  54. ParagraphSpacing = 8,
  55. MarginLeft = Layout.ListOffset,
  56. };
  57. tl.DefaultFormat.Font = StandardFonts.Times;
  58.  
  59. // Add 20 paragraphs of text that will render as a numbered list of 20 items:
  60. tl.Append(Common.Util.LoremIpsum(20, 1, 6));
  61. // Perform layout:
  62. tl.PerformLayout(true);
  63. // Use split options to provide widow/orphan control:
  64. var to = new TextSplitOptions(tl);
  65. to.MinLinesInFirstParagraph = 2;
  66. to.MinLinesInLastParagraph = 2;
  67. // In a loop, split and render the text (see PaginatedText),
  68. // and add list numbers:
  69. int itemNo = 1;
  70. while (true)
  71. {
  72. // 'rest' will accept the text that did not fit:
  73. var splitResult = tl.Split(to, out TextLayout rest);
  74. var g = doc.Pages.Add().Graphics;
  75. g.DrawTextLayout(tl, ip);
  76. AddBullets(g, ip, tl, ref itemNo);
  77. if (splitResult != SplitResult.Split)
  78. break;
  79. tl = rest;
  80. }
  81. // Done:
  82. doc.Save(stream);
  83. return doc.Pages.Count;
  84. }
  85. }
  86. }
  87.