PageHeaders.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 a simple way to generate left/centered/right aligned page headers and footers.
  15. public class PageHeaders
  16. {
  17. // The document being generated:
  18. private GcPdfDocument _doc;
  19.  
  20. // Utility method to draw a part of a page header or footer.
  21. // Parameters:
  22. // - text: The part's text.
  23. // - tf: The text format to use.
  24. // - pageIdx: The page index.
  25. // - header: True if this is a header, false if a footer.
  26. // - horzAlign: Horizontal alignment (left/center/right).
  27. private void RenderHeader(string text, TextFormat tf, int pageIdx, bool header, TextAlignment horzAlign)
  28. {
  29. var page = _doc.Pages[pageIdx];
  30. var tl = new TextLayout(page.Graphics.Resolution);
  31. tl.MaxWidth = page.Size.Width;
  32. tl.MaxHeight = page.Size.Height;
  33. // 1" margins, adjust as needed:
  34. tl.MarginLeft = tl.MarginRight = tl.Resolution;
  35. // 1/3" spacing above top/below bottom header, adjust as needed:
  36. tl.MarginTop = tl.MarginBottom = tl.Resolution / 3;
  37. // Vertical alignment:
  38. tl.ParagraphAlignment = header ? ParagraphAlignment.Near : ParagraphAlignment.Far;
  39. // Horizontal alignment:
  40. tl.TextAlignment = horzAlign;
  41. tl.Append(text, tf);
  42. // NOTE: if some part of a header or footer is static, we could cache the corresponding TextLayout
  43. // object and save some cycles by just drawing that cached TextLayout on each page w/out anything else:
  44. tl.PerformLayout(true);
  45. // Draw the header at (0,0) (header located by margins and alignment):
  46. page.Graphics.DrawTextLayout(tl, PointF.Empty);
  47. }
  48.  
  49. // The main program.
  50. public int CreatePDF(Stream stream)
  51. {
  52. _doc = new GcPdfDocument();
  53. var page = _doc.NewPage();
  54. // Add a note about flipping landscape:
  55. var noteRect = Common.Util.AddNote(
  56. "We flip page orientation in this sample only to show that these page headers can adapt to the changing page size.",
  57. page);
  58. // Prepare a TextLayout with some long text and print it (see PaginatedText for details):
  59. var tl = page.Graphics.CreateTextLayout();
  60. tl.DefaultFormat.Font = StandardFonts.Times;
  61. tl.DefaultFormat.FontSize = 12;
  62. tl.MaxWidth = _doc.PageSize.Width;
  63. tl.MaxHeight = _doc.PageSize.Height;
  64. tl.MarginAll = tl.Resolution;
  65. tl.MarginTop = noteRect.Bottom + 18;
  66. // Add sample text:
  67. tl.Append(Common.Util.LoremIpsum(20));
  68. // Calculate glyphs and perform layout (see also PerformLayout call in the loop below):
  69. tl.PerformLayout(true);
  70. // In a loop, split and render the text:
  71. while (true)
  72. {
  73. var splitResult = tl.Split(null, out TextLayout rest);
  74. page.Graphics.DrawTextLayout(tl, PointF.Empty);
  75. if (splitResult != SplitResult.Split)
  76. break;
  77. tl = rest;
  78. tl.MarginTop = tl.Resolution;
  79. page = _doc.Pages.Add();
  80. // For sample sake, toggle page orientation:
  81. page.Landscape = !_doc.Pages[_doc.Pages.Count - 2].Landscape;
  82. // Update layout size to reflect the new page orientation:
  83. tl.MaxWidth = page.Size.Width;
  84. tl.MaxHeight = page.Size.Height;
  85. // Because we changed layout size, we must perform layout again -
  86. // but can do it without recalculating glyphs:
  87. tl.PerformLayout(false);
  88. }
  89. // Render the headers in a separate loop (so that we can provide 'Page X of Y' header):
  90. var tf = new TextFormat() { Font = StandardFonts.Helvetica, FontSize = 10, ForeColor = Color.Gray };
  91. var now = Common.Util.TimeNow().ToString("u");
  92. for (int pageIdx = 0; pageIdx < _doc.Pages.Count; ++pageIdx)
  93. {
  94. RenderHeader(now, tf, pageIdx, true, TextAlignment.Leading);
  95. RenderHeader("Easy Page Headers Sample", tf, pageIdx, true, TextAlignment.Center);
  96. RenderHeader($"Page {pageIdx + 1} of {_doc.Pages.Count}", tf, pageIdx, true, TextAlignment.Trailing);
  97. RenderHeader("Page footer - left", tf, pageIdx, false, TextAlignment.Leading);
  98. RenderHeader("DsPdf", tf, pageIdx, false, TextAlignment.Center);
  99. RenderHeader("Page footer - right", tf, pageIdx, false, TextAlignment.Trailing);
  100. }
  101. // Done:
  102. _doc.Save(stream);
  103. return _doc.Pages.Count;
  104. }
  105. }
  106. }
  107.