TextAroundImages.vb
- ''
- '' This code is part of Document Solutions for PDF demos.
- '' Copyright (c) MESCIUS inc. All rights reserved.
- ''
- Imports System.IO
- Imports System.Drawing
- Imports GrapeCity.Documents.Pdf
- Imports GrapeCity.Documents.Text
- Imports GrapeCity.Documents.Drawing
- Imports GCTEXT = GrapeCity.Documents.Text
- Imports GCDRAW = GrapeCity.Documents.Drawing
-
- '' This sample shows how to flow a large block of text around rectangular areas,
- '' in this case images. It also demonstrates how to get the actual bounds
- '' of an image that has been rendered on a page using a specific ImageAlign.
- Public Class TextAroundImages
- Function CreatePDF(ByVal stream As Stream) As Integer
- Dim doc = New GcPdfDocument()
- Dim g = doc.NewPage().Graphics
- ''
- '' We want to draw 3 images in certain arbitrary locations on the first page,
- '' and then print a text that would take 2-3 pages, and have it flow around
- '' the images on the first page.
- ''
- '' Get the images and their rectangles. Note that we specify a square
- '' area for all images - but they will be aligned within that area
- '' preserving their original aspect ratios, so we will later retrieve
- '' the actual rectangles where the images were drawn:
- Using imgPuffins As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "puffins.jpg")),
- imgReds As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "reds.jpg")),
- imgLavender As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "lavender.jpg"))
- Dim rectPuffins = New RectangleF(100, 70, 180, 180)
- Dim rectReds = New RectangleF(300, 280, 180, 180)
- Dim rectLavender = New RectangleF(190, 510, 180, 180)
- '' Set up ImageAlign that would fit and center an image within a specified area,
- '' preserving the image's original aspect ratio:
- Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, True, True, True, False, False)
- '' Draw each image, providing an array of rectangles as an output parameter for each DrawImage call,
- '' so that we get the actual rectangle taken by the image (an array is needed to handle tiled images):
- Dim rectsPuffins As RectangleF() = Nothing
- g.DrawImage(imgPuffins, rectPuffins, Nothing, ia, rectsPuffins)
- Dim rectsReds As RectangleF() = Nothing
- g.DrawImage(imgReds, rectReds, Nothing, ia, rectsReds)
- Dim rectsLavender As RectangleF() = Nothing
- g.DrawImage(imgLavender, rectLavender, Nothing, ia, rectsLavender)
- '' Create and set up a TextLayout object to print the text:
- Dim tl = g.CreateTextLayout()
- tl.DefaultFormat.Font = StandardFonts.Times
- tl.DefaultFormat.FontSize = 9
- tl.TextAlignment = TextAlignment.Justified
- tl.ParagraphSpacing = 72 / 8
- tl.MaxWidth = doc.PageSize.Width
- tl.MaxHeight = doc.PageSize.Height
- '' 1/2" margins all around
- tl.MarginAll = 72 / 2
- '' ObjectRect is the type used to specify the areas to flow around to TextLayout.
- '' We set up a local function to create an ObjecRect based on an image rectangle,
- '' adding some padding so that the result looks nicer:
- Dim makeObjectRect As Func(Of RectangleF, ObjectRect) =
- Function(ByVal rect_)
- Return New ObjectRect(rect_.X - 6, rect_.Y - 2, rect_.Width + 12, rect_.Height + 4)
- End Function
- '' Specify the array of ObjectRects on the TextLayout:
- tl.ObjectRects = New List(Of ObjectRect)() From {
- makeObjectRect(rectsPuffins(0)),
- makeObjectRect(rectsReds(0)),
- makeObjectRect(rectsLavender(0))
- }
- '' Add several paragraphs of text:
- tl.Append(Util.LoremIpsum(7, 5, 6, 28, 32))
- '' Calculate glyphs and lay out the text:
- tl.PerformLayout(True)
- '' Split options to control splitting of text between pages.
- '' We can either use the default ctor and set up values like MaxWidth etc,
- '' or create a TextSplitOptions based on the TextLayout, and clear RestObjectRects:
- Dim tso = New TextSplitOptions(tl) With {
- .RestObjectRects = Nothing,
- .MinLinesInFirstParagraph = 2,
- .MinLinesInLastParagraph = 2
- }
- '' In a loop, split and render the text:
- While True
- '' 'rest' will accept the text that did not fit:
- Dim rest As TextLayout = Nothing
- Dim splitResult = tl.Split(tso, rest)
- doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty)
- If splitResult <> SplitResult.Split Then
- Exit While
- End If
- tl = rest
- '' We only draw images on the first page:
- tl.ObjectRects = Nothing
- doc.Pages.Add()
- End While
- ''
- '' Done:
- doc.Save(stream)
- Return doc.Pages.Count
- End Using
- End Function
- End Class
-