DropCap.vb
  1. ''
  2. '' This code is part of Document Solutions for PDF demos.
  3. '' Copyright (c) MESCIUS inc. All rights reserved.
  4. ''
  5. Imports System.IO
  6. Imports System.Drawing
  7. Imports GrapeCity.Documents.Pdf
  8. Imports GrapeCity.Documents.Text
  9. Imports GCTEXT = GrapeCity.Documents.Text
  10. Imports GCDRAW = GrapeCity.Documents.Drawing
  11.  
  12. '' Demonstrates how to create a drop cap in DsPdf.
  13. Public Class DropCap
  14. Function CreatePDF(ByVal stream As Stream) As Integer
  15. Dim doc = New GcPdfDocument()
  16. Dim g = doc.NewPage().Graphics
  17. '' Get some text and split it into first letter (drop cap) and the rest:
  18. Dim text = Util.LoremIpsum(1)
  19. Dim head = text.Substring(0, 1)
  20. Dim tail = text.Substring(1)
  21. '' Use the Times font:
  22. Dim fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf"))
  23. '' Text layout for the drop cap:
  24. Dim tlHead = g.CreateTextLayout()
  25. tlHead.DefaultFormat.Font = fnt
  26. tlHead.DefaultFormat.FontSize = 40
  27. tlHead.Append(head)
  28. tlHead.PerformLayout(True)
  29. '' Text layout for the rest of the text:
  30. Dim tlTail = g.CreateTextLayout()
  31. tlTail.DefaultFormat.Font = fnt
  32. tlTail.DefaultFormat.FontSize = 12
  33. '' Use whole page with 1" margins all around:
  34. tlTail.MaxWidth = doc.Pages.Last.Size.Width - 72 * 2
  35. tlTail.MaxHeight = doc.Pages.Last.Size.Height - 72 * 2
  36. tlTail.Append(tail)
  37. '' Before we layout the main body of the text, we calculate the size and position
  38. '' of the drop cap rectangle, and add it to the main text layout's ObjectRects -
  39. '' the list of rectangles that the main text will flow around.
  40. ''
  41. '' Note: While we could simply position the drop cap rectangle at the top/left of the
  42. '' main text, it looks better if the tops of the drop cap and the main text's glyphs
  43. '' are aligned. For this, we need to calculate the offets of letter tops within
  44. '' the text bounding boxes, and adjust the position of the drop cap accordingly
  45. '' (raise it a little).
  46. '' (For this adjustment we need the sCapHeight field which is present if the font's
  47. '' os/2 table version 2 and higher, so we must test for that and skip this step if
  48. '' the CapHeight is not available).
  49. Dim dy = 0F
  50. If fnt.CapHeight <> -1 Then
  51. '' We move the drop cap position up by the amount equal to the difference between the
  52. '' top spacing within the Em square of the drop cap's font size and the font size of the rest of the text:
  53. Dim k = tlHead.DefaultFormat.FontSize * tlHead.Resolution * tlHead.FontScaleFactor / (fnt.UnitsPerEm * 72)
  54. dy = (fnt.HorizontalAscender - fnt.CapHeight) * k
  55. k /= tlHead.DefaultFormat.FontSize
  56. k *= tlTail.DefaultFormat.FontSize
  57. dy -= (fnt.HorizontalAscender - fnt.SmallXHeight) * k
  58. End If
  59. '' Specify the rectangle for the main text to flow around:
  60. tlTail.ObjectRects = New List(Of ObjectRect) From {New ObjectRect(0, -dy, tlHead.ContentWidth * 1.2F, tlHead.ContentHeight)}
  61. '' Layout the main text now:
  62. tlTail.PerformLayout(True)
  63. '' Draw everything:
  64. g.DrawTextLayout(tlHead, New PointF(72, 72 - dy))
  65. g.DrawTextLayout(tlTail, New PointF(72, 72))
  66. ''
  67. '' Done:
  68. doc.Save(stream)
  69. Return doc.Pages.Count
  70. End Function
  71. End Class
  72.