TextRendering.vb
  1. ''
  2. '' This code is part of Document Solutions for Imaging demos.
  3. '' Copyright (c) MESCIUS inc. All rights reserved.
  4. ''
  5. Imports System.IO
  6. Imports System.Drawing
  7. Imports System.Numerics
  8. Imports GrapeCity.Documents.Drawing
  9. Imports GrapeCity.Documents.Text
  10. Imports GrapeCity.Documents.Imaging
  11. Imports GCTEXT = GrapeCity.Documents.Text
  12. Imports GCDRAW = GrapeCity.Documents.Drawing
  13.  
  14. '' Demonstrates the basics of rendering text in DsImaging.
  15. '' The two main approaches are:
  16. '' - using the MeasureString/DrawString pair, or
  17. '' - using the TextLayout directly.
  18. '' While the first approach may be easier in simple cases,
  19. '' the second approach (using TextLayout) is much more powerful
  20. '' and generally speaking yields better performance.
  21. '' Please read the comments in code below for more details.
  22. Public Class TextRendering
  23. Function GenerateImage(
  24. ByVal pixelSize As Size,
  25. ByVal dpi As Single,
  26. ByVal opaque As Boolean,
  27. Optional ByVal sampleParams As String() = Nothing) As GcBitmap
  28.  
  29. Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, True, dpi, dpi)
  30. Dim Inch = dpi
  31. Const fontSize = 14
  32. Using g = bmp.CreateGraphics(Color.White)
  33. '' TextFormat class Is used throughout all DsImaging text rendering to specify
  34. '' font And other character formatting:
  35. Dim tf = New TextFormat() With
  36. {
  37. .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
  38. .FontSize = fontSize
  39. }
  40.  
  41. '' 1.
  42. '' The easiest way to render a short string on a page at an arbitrary location,
  43. '' when you are 100% sure that the string will fit in the available space,
  44. '' Is to use the GcGraphics.DrawString() overload accepting just the point
  45. '' at which to draw the string:
  46. g.DrawString(
  47. "1. Test string. Please read the extensive comments in this sample's code." + vbCrLf +
  48. "(Note that line breaks are allowed even in the simplest DrawString overload.)",
  49. tf, New PointF(Inch, Inch))
  50.  
  51. '' 2.
  52. '' Another overload taking a rectangle instead, plus alignment And wrapping
  53. '' options, Is also available And provides a bit more flexibility:
  54. g.DrawString(
  55. "2. A longer test string which will probably need more than the allocated " +
  56. "4 inches so quite possibly will wrap to show that DrawString can do that.",
  57. tf,
  58. New RectangleF(Inch, Inch * 2, Inch * 4, Inch),
  59. TextAlignment.Leading,
  60. ParagraphAlignment.Near,
  61. True)
  62.  
  63. '' 3.
  64. '' Complementary to DrawString, a MeasureString() method Is available
  65. '' (with several different overloads), And can be used in pair with
  66. '' DrawString when more control over text layout Is needed
  67. Const tstr3 = "3. Test string to demo MeasureString() used with DrawString()."
  68.  
  69. Dim layoutSize = New SizeF(Inch * 3, Inch * 0.8F) '' available size
  70. Dim fitCharCount As Integer
  71. Dim s = g.MeasureString(tstr3, tf, layoutSize, fitCharCount)
  72. '' Show the passed in size in red, the measured size in blue,
  73. '' And draw the string within the returned size as bounds:
  74. Dim pt = New PointF(Inch, Inch * 3)
  75. g.DrawRectangle(New RectangleF(pt, layoutSize), Color.Red)
  76. g.DrawRectangle(New RectangleF(pt, s), Color.Blue)
  77. g.DrawString(tstr3, tf, New RectangleF(pt, s))
  78.  
  79. '' 4.
  80. '' A much more powerful And with better performance, way to render text
  81. '' Is to use TextLayout. (TextLayout Is used anyway by DrawString/MeasureString,
  82. '' so when you use TextLayout directly, you basically cut the work in half.)
  83. '' A TextLayout instance represents one Or more paragraphs of text, with
  84. '' the same paragraph formatting (character formats may be different,
  85. '' see {MultiFormattedText}).
  86. Dim tl = g.CreateTextLayout()
  87. '' To add text, use Append() Or AppendLine() methods:
  88. tl.Append("4. First test string added to TextLayout. ", tf)
  89. tl.Append("Second test string added to TextLayout, continuing the same paragraph. ", tf)
  90. tl.AppendLine() '' Add a line break, effectively starting a New paragraph
  91. tl.Append("Third test string added to TextLayout, a new paragraph. ", tf)
  92. tl.Append("Fourth test string, with a different char formatting. ",
  93. New TextFormat(tf) With
  94. {
  95. .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "timesbi.ttf")),
  96. .FontSize = fontSize,
  97. .FontBold = True,
  98. .FontItalic = True,
  99. .ForeColor = Color.DarkSeaGreen
  100. })
  101. '' Text can be added to TextLayout without explicit TextFormat:
  102. tl.Append("Fifth test string, using the TextLayout's default format.")
  103. '' ...but in that case at least the Font must be specified on the
  104. '' TextLayout's DefaultFormat, otherwise PerformLayout (below) will fail:
  105. tl.DefaultFormat.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "timesi.ttf"))
  106. tl.DefaultFormat.FontSize = fontSize
  107.  
  108. '' Specify the layout, such as max available size etc.
  109. '' Here we only provide the max width, but many more parameters can be set:
  110. tl.MaxWidth = g.Width - Inch * 2
  111. '' Paragraph formatting can also be set, here we set first line offset,
  112. '' spacing between paragraphs And line spacing:
  113. tl.FirstLineIndent = Inch * 0.5F
  114. tl.ParagraphSpacing = Inch * 0.05F
  115. tl.LineSpacingScaleFactor = 0.8F
  116.  
  117. '' When all text has been added, And layout options specified,
  118. '' the TextLayout needs to calculate the glyphs needed to render
  119. '' the text, And perform the layout. This can be done with a
  120. '' single call:
  121. tl.PerformLayout(True)
  122.  
  123. '' Now we can draw it on the page
  124. pt = New PointF(Inch, Inch * 4)
  125. g.DrawTextLayout(tl, pt)
  126. '' TextLayout provides info about the text including the measured bounds
  127. '' And much more. Here we draw the bounding box in orange red:
  128. g.DrawRectangle(New RectangleF(pt, tl.ContentRectangle.Size), Color.OrangeRed)
  129.  
  130. '' 5.
  131. '' TextLayout can be re-used to draw different paragraph(s), this can be useful
  132. '' when you need to render a different text with the same paragraph formatting.
  133. '' The Clear() call removes the text but preserves paragraph formatting:
  134. tl.Clear()
  135. tl.Append("5. This is text rendered re-using the same TextLayout. ")
  136. tl.Append("More text added to TextLayout being re-used, continuing the same paragraph. ", tf)
  137. tl.Append("And finally, some more text added.", tf)
  138. '' The necessary call to calculate the glyphs And perform layout:
  139. tl.PerformLayout(True)
  140. '' Render the text:
  141. g.DrawTextLayout(tl, New PointF(Inch, Inch * 5))
  142. '' Draw border around the whole image:
  143. g.DrawRectangle(New RectangleF(0, 0, bmp.Width, bmp.Height), Color.DarkSlateBlue, 4)
  144. End Using
  145. '' Done
  146. Return bmp
  147. End Function
  148. End Class
  149.