DropCap.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.Collections.Generic;
  7. using System.IO;
  8. using System.Drawing;
  9. using GrapeCity.Documents.Pdf;
  10. using GrapeCity.Documents.Text;
  11. using GCTEXT = GrapeCity.Documents.Text;
  12. using GCDRAW = GrapeCity.Documents.Drawing;
  13.  
  14. namespace DsPdfWeb.Demos.Basics
  15. {
  16. // This sample demonstrates how to create a drop cap in DsPdf.
  17. public class DropCap
  18. {
  19. public int CreatePDF(Stream stream)
  20. {
  21. var doc = new GcPdfDocument();
  22. var g = doc.NewPage().Graphics;
  23. // Get some text and split it into first letter (drop cap) and the rest:
  24. var text = Common.Util.LoremIpsum(1);
  25. var head = text.Substring(0, 1);
  26. var tail = text.Substring(1);
  27. // Use the Times font:
  28. var font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf"));
  29. // Text layout for the drop cap:
  30. var tlHead = g.CreateTextLayout();
  31. tlHead.DefaultFormat.Font = font;
  32. tlHead.DefaultFormat.FontSize = 40;
  33. tlHead.Append(head);
  34. tlHead.PerformLayout(true);
  35. // Text layout for the rest of the text:
  36. var tlTail = g.CreateTextLayout();
  37. tlTail.DefaultFormat.Font = font;
  38. tlTail.DefaultFormat.FontSize = 12;
  39. // Use whole page with 1" margins all around:
  40. tlTail.MaxWidth = doc.Pages.Last.Size.Width - 72 * 2;
  41. tlTail.MaxHeight = doc.Pages.Last.Size.Height - 72 * 2;
  42. tlTail.Append(tail);
  43. // Before we layout the main body of the text, we calculate the size and position
  44. // of the drop cap rectangle, and add it to the main text layout's ObjectRects -
  45. // the list of rectangles that the main text will flow around.
  46. //
  47. // Note: While we could simply position the drop cap rectangle at the top/left of the
  48. // main text, it looks better if the tops of the drop cap and the main text's glyphs
  49. // are aligned. For this, we need to calculate the offsets of letter tops within
  50. // the text bounding boxes, and adjust the position of the drop cap accordingly
  51. // (raise it a little).
  52. // (For this adjustment we need the sCapHeight field which is present if the font's
  53. // os/2 table version 2 and higher, so we must test for that and skip this step if
  54. // the CapHeight is not available).
  55. float dy = 0;
  56. if (font.CapHeight != -1)
  57. {
  58. // We move the drop cap position up by the amount equal to the difference between the
  59. // top spacing within the Em square of the drop cap's font size and the font size of the rest of the text:
  60. float k = tlHead.DefaultFormat.FontSize * tlHead.Resolution * tlHead.FontScaleFactor / (font.UnitsPerEm * 72);
  61. dy = (font.HorizontalAscender - font.CapHeight) * k;
  62. k /= tlHead.DefaultFormat.FontSize;
  63. k *= tlTail.DefaultFormat.FontSize;
  64. dy -= (font.HorizontalAscender - font.SmallXHeight) * k;
  65. }
  66. // Specify the rectangle for the main text to flow around:
  67. tlTail.ObjectRects = new List<ObjectRect>() { new ObjectRect(0, -dy, tlHead.ContentWidth * 1.2f, tlHead.ContentHeight) };
  68. // Layout the main text now:
  69. tlTail.PerformLayout(true);
  70. // Draw everything:
  71. g.DrawTextLayout(tlHead, new PointF(72, 72 - dy));
  72. g.DrawTextLayout(tlTail, new PointF(72, 72));
  73. // Done:
  74. doc.Save(stream);
  75. return doc.Pages.Count;
  76. }
  77. }
  78. }
  79.