TextAroundImages.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. Imports GCTEXT = GrapeCity.Documents.Text
  11. Imports GCDRAW = GrapeCity.Documents.Drawing
  12.  
  13. '' This sample shows how to flow a large block of text around rectangular areas,
  14. '' in this case images. It also demonstrates how to get the actual bounds
  15. '' of an image that has been rendered on a page using a specific ImageAlign.
  16. Public Class TextAroundImages
  17. Function CreatePDF(ByVal stream As Stream) As Integer
  18. Dim doc = New GcPdfDocument()
  19. Dim g = doc.NewPage().Graphics
  20. ''
  21. '' We want to draw 3 images in certain arbitrary locations on the first page,
  22. '' and then print a text that would take 2-3 pages, and have it flow around
  23. '' the images on the first page.
  24. ''
  25. '' Get the images and their rectangles. Note that we specify a square
  26. '' area for all images - but they will be aligned within that area
  27. '' preserving their original aspect ratios, so we will later retrieve
  28. '' the actual rectangles where the images were drawn:
  29. Using imgPuffins As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "puffins.jpg")),
  30. imgReds As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "reds.jpg")),
  31. imgLavender As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "lavender.jpg"))
  32. Dim rectPuffins = New RectangleF(100, 70, 180, 180)
  33. Dim rectReds = New RectangleF(300, 280, 180, 180)
  34. Dim rectLavender = New RectangleF(190, 510, 180, 180)
  35. '' Set up ImageAlign that would fit and center an image within a specified area,
  36. '' preserving the image's original aspect ratio:
  37. Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, True, True, True, False, False)
  38. '' Draw each image, providing an array of rectangles as an output parameter for each DrawImage call,
  39. '' so that we get the actual rectangle taken by the image (an array is needed to handle tiled images):
  40. Dim rectsPuffins As RectangleF() = Nothing
  41. g.DrawImage(imgPuffins, rectPuffins, Nothing, ia, rectsPuffins)
  42. Dim rectsReds As RectangleF() = Nothing
  43. g.DrawImage(imgReds, rectReds, Nothing, ia, rectsReds)
  44. Dim rectsLavender As RectangleF() = Nothing
  45. g.DrawImage(imgLavender, rectLavender, Nothing, ia, rectsLavender)
  46. '' Create and set up a TextLayout object to print the text:
  47. Dim tl = g.CreateTextLayout()
  48. tl.DefaultFormat.Font = StandardFonts.Times
  49. tl.DefaultFormat.FontSize = 9
  50. tl.TextAlignment = TextAlignment.Justified
  51. tl.ParagraphSpacing = 72 / 8
  52. tl.MaxWidth = doc.PageSize.Width
  53. tl.MaxHeight = doc.PageSize.Height
  54. '' 1/2" margins all around
  55. tl.MarginAll = 72 / 2
  56. '' ObjectRect is the type used to specify the areas to flow around to TextLayout.
  57. '' We set up a local function to create an ObjecRect based on an image rectangle,
  58. '' adding some padding so that the result looks nicer:
  59. Dim makeObjectRect As Func(Of RectangleF, ObjectRect) =
  60. Function(ByVal rect_)
  61. Return New ObjectRect(rect_.X - 6, rect_.Y - 2, rect_.Width + 12, rect_.Height + 4)
  62. End Function
  63. '' Specify the array of ObjectRects on the TextLayout:
  64. tl.ObjectRects = New List(Of ObjectRect)() From {
  65. makeObjectRect(rectsPuffins(0)),
  66. makeObjectRect(rectsReds(0)),
  67. makeObjectRect(rectsLavender(0))
  68. }
  69. '' Add several paragraphs of text:
  70. tl.Append(Util.LoremIpsum(7, 5, 6, 28, 32))
  71. '' Calculate glyphs and lay out the text:
  72. tl.PerformLayout(True)
  73. '' Split options to control splitting of text between pages.
  74. '' We can either use the default ctor and set up values like MaxWidth etc,
  75. '' or create a TextSplitOptions based on the TextLayout, and clear RestObjectRects:
  76. Dim tso = New TextSplitOptions(tl) With {
  77. .RestObjectRects = Nothing,
  78. .MinLinesInFirstParagraph = 2,
  79. .MinLinesInLastParagraph = 2
  80. }
  81. '' In a loop, split and render the text:
  82. While True
  83. '' 'rest' will accept the text that did not fit:
  84. Dim rest As TextLayout = Nothing
  85. Dim splitResult = tl.Split(tso, rest)
  86. doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty)
  87. If splitResult <> SplitResult.Split Then
  88. Exit While
  89. End If
  90. tl = rest
  91. '' We only draw images on the first page:
  92. tl.ObjectRects = Nothing
  93. doc.Pages.Add()
  94. End While
  95. ''
  96. '' Done:
  97. doc.Save(stream)
  98. Return doc.Pages.Count
  99. End Using
  100. End Function
  101. End Class
  102.