TextRendering.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 GrapeCity.Documents.Drawing
  10.  
  11. '' This sample demonstrates the basics of rendering text in DsPdf.
  12. '' The two main approaches are:
  13. '' - using the MeasureString/DrawString pair, or
  14. '' - using the TextLayout directly.
  15. '' While the first approach may be easier in simple cases,
  16. '' the second approach (using TextLayout) is much more powerful
  17. '' and generally speaking yields better performance.
  18. '' Please read the comments in code below for more details.
  19. '' See also CharacterFormatting, PaginatedText, ParagraphAlign,
  20. '' ParagraphFormatting, TextAlign.
  21. Public Class TextRendering
  22. Function CreatePDF(ByVal stream As Stream) As Integer
  23. Dim doc = New GcPdfDocument()
  24. Dim page = doc.NewPage()
  25. Dim g = page.Graphics
  26. '' By default, DsPdf uses 72dpi:
  27. Const Inch = 72.0F
  28.  
  29. '' TextFormat class is used throughout all DsPdf text rendering to specify
  30. '' font and other character formatting:
  31. Dim tf = New TextFormat() With {.Font = StandardFonts.Times, .FontSize = 12}
  32.  
  33. '' 1.
  34. '' The easiest way to render a short string on a page at an arbitrary location,
  35. '' when you are 100% sure that the string will fit in the available space,
  36. '' is to use the GcGraphics.DrawString() overload accepting jus the point
  37. '' at which to draw the string:
  38. g.DrawString("1. Test string. Please read the extensive comments in this sample's code." +
  39. "(Note that line breaks are allowed even in the simplest DrawString overload.)", tf, New PointF(Inch, Inch))
  40.  
  41. '' 2.
  42. '' Another overload taking a rectangle instead, plus alignment and wrapping
  43. '' options, is also available and provides a bit more flexibility.
  44. '' The parameters are:
  45. '' - text
  46. '' - format
  47. '' - the layout rectangle
  48. '' The rest 3 args are optional, passing defaults here for illustration:
  49. '' - leading (left for LTR languages) text align
  50. '' - near (top for top-to-bottom flow) para align
  51. '' - word wrap
  52. g.DrawString("2. A longer test string which will probably need more than the allocated" +
  53. "4 inches so quite possibly will wrap to show that DrawString can do that.",
  54. tf,
  55. New RectangleF(Inch, Inch * 2, Inch * 4, Inch),
  56. TextAlignment.Leading,
  57. ParagraphAlignment.Near,
  58. True)
  59.  
  60. '' 3.
  61. '' Complementary to DrawString, a MeasureString() method is available
  62. '' (with several different overloads), and can be used in pair with
  63. '' DrawString when more control over text layout is needed:
  64. Dim tstr3 = "3. Test string to demo MeasureString() used with DrawString()."
  65.  
  66. Dim layoutSize = New SizeF(Inch * 3, Inch * 0.8F) '' available size
  67. Dim fitCharCount As Integer
  68. Dim s = g.MeasureString(tstr3, tf, layoutSize, fitCharCount)
  69. '' Show the passed in size in red, the measured size in blue,
  70. '' and draw the string within the returned size as bounds:
  71. Dim pt = New PointF(Inch, Inch * 3)
  72. g.DrawRectangle(New RectangleF(pt, layoutSize), Color.Red)
  73. g.DrawRectangle(New RectangleF(pt, s), Color.Blue)
  74. g.DrawString(tstr3, tf, New RectangleF(pt, s))
  75.  
  76. '' 4.
  77. '' A much more powerful and with better performance, way to render text
  78. '' is to use TextLayout. (TextLayout is used anyway by DrawString/MeasureString,
  79. '' so when you use TextLayout directly, you basically cut the work in half.)
  80. '' A TextLayout instance represents one or more paragraphs of text, with
  81. '' the same paragraph formatting (character formats may be different,
  82. '' see {MultiFormattedText}).
  83. Dim tl = g.CreateTextLayout()
  84. '' To add text, use Append() or AppendLine() methods:
  85. tl.Append("4. First test string added to TextLayout. ", tf)
  86. tl.Append("Second test string added to TextLayout, continuing the same paragraph. ", tf)
  87. tl.AppendLine() '' Add a line break, effectively starting a new paragraph
  88. tl.Append("Third test string added to TextLayout, a new paragraph. ", tf)
  89. tl.Append("Fourth test string, with a different char formatting. ",
  90. New TextFormat(tf) With {.Font = StandardFonts.TimesBoldItalic, .ForeColor = Color.DarkSeaGreen})
  91. '' Text can be added to TextLayout without explicit TextFormat:
  92. tl.Append("Fifth test string, using the TextLayout's default format.")
  93. '' ...but in that case at least the Font must be specified on the
  94. '' TextLayout's DefaultFormat, otherwise PerformLayout (below) will fail:
  95. tl.DefaultFormat.Font = StandardFonts.TimesItalic
  96.  
  97. '' Specify the layout, such as max available size etc.
  98. '' Here we only provide the max width, but many more parameters can be set:
  99. tl.MaxWidth = page.Size.Width - Inch * 2
  100. '' Paragraph formatting can also be set, here we set first line offset,
  101. '' spacing between paragraphs and line spacing:
  102. tl.FirstLineIndent = Inch * 0.5F
  103. tl.ParagraphSpacing = Inch * 0.05F
  104. tl.LineSpacingScaleFactor = 0.8F
  105.  
  106. '' When all text has been added, and layout options specified,
  107. '' the TextLayout needs to calculate the glyphs needed to render
  108. '' the text, and perform the layout. This can be done with a
  109. '' single call:
  110. tl.PerformLayout(True)
  111.  
  112. '' Now we can draw it on the page:
  113. pt = New PointF(Inch, Inch * 4)
  114. g.DrawTextLayout(tl, pt)
  115. '' TextLayout provides info about the text including the measured bounds
  116. '' and much more. Here we draw the bounding box in orange red:
  117. g.DrawRectangle(New RectangleF(pt, tl.ContentRectangle.Size), Color.OrangeRed)
  118.  
  119. '' 5.
  120. '' TextLayout can be re-used to draw different paragraph(s), this can be useful
  121. '' when you need to render a different text with the same paragraph formatting.
  122. '' The Clear() call removes the text but preserves paragraph formatting:
  123. tl.Clear()
  124. tl.Append("5. This is text rendered re-using the same TextLayout. ")
  125. tl.Append("More text added to TextLayout being re-used, continuing the same paragraph. ", tf)
  126. tl.Append("And finally, some more text added.", tf)
  127. '' The necessary call to calculate the glyphs and perform layout:
  128. tl.PerformLayout(True)
  129. '' Render the text:
  130. g.DrawTextLayout(tl, New PointF(Inch, Inch * 5))
  131. ''
  132. '' Done:
  133. doc.Save(stream)
  134. Return doc.Pages.Count
  135. End Function
  136. End Class
  137.