''
'' 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
'' Creates a multi-column text layout with balanced columns.
'' The heart of this sample is the TextLayout.SplitAndBalance() method
'' which allows splitting a text between multiple columns,
'' AND balance those columns so that their heights are similar,
'' thus allowing to produce magazine- and newspaper-like text layouts.
Public Class BalancedColumns
Function CreatePDF(ByVal stream As Stream) As Integer
Dim doc = New GcPdfDocument()
Dim font = StandardFonts.Times
Dim fontSize = 12
'' 1/2" margins all around (72 dpi is the default resolution used by DsPdf):
Dim margin = 72 / 2
Dim pageWidth = doc.PageSize.Width
Dim pageHeight = doc.PageSize.Height
Dim cW = pageWidth - margin * 2
'' Text format for the chapter titles:
Dim tlCaption = New TextLayout(72)
tlCaption.DefaultFormat.Font = font
tlCaption.DefaultFormat.FontSize = fontSize + 4
tlCaption.DefaultFormat.Underline = True
tlCaption.MaxWidth = pageWidth
tlCaption.MaxHeight = pageHeight
tlCaption.MarginLeft = margin
tlCaption.MarginTop = margin
tlCaption.MarginRight = margin
tlCaption.MarginBottom = margin
tlCaption.TextAlignment = TextAlignment.Center
'' Height of chapter caption (use a const for simplicity):
Const captionH = 24.0F
'' Text layout for main document body (default DsPdf resolution is 72dpi):
Dim tl = New TextLayout(72)
tl.DefaultFormat.Font = font
tl.DefaultFormat.FontSize = fontSize
tl.FirstLineIndent = 72 / 2
tl.MaxWidth = pageWidth
tl.MaxHeight = pageHeight
tl.MarginLeft = margin
tl.MarginRight = margin
tl.MarginBottom = margin
tl.MarginTop = margin + captionH
tl.ColumnWidth = cW * 0.3F
tl.TextAlignment = TextAlignment.Justified
'' Array of PageSplitArea's which control additional columns (1st column is controlled by
'' the 'main' TextLayout, for each additional one a PageSplitArea must be provided -
'' it will create and return a TextLayout that can then be used to render the column):
Dim psas As PageSplitArea() = {
New PageSplitArea(tl) With {.MarginLeft = tl.MarginLeft + (cW * 0.35F)},
New PageSplitArea(tl) With {.ColumnWidth = -cW * 0.3F}
}
'' Split options to control splitting text between pages:
Dim tso = New TextSplitOptions(tl) With {
.RestMarginTop = margin,
.MinLinesInFirstParagraph = 2,
.MinLinesInLastParagraph = 2
}
'' Generate a number of "chapters", provide outline entry for each:
Const NChapters = 20
doc.Pages.Add()
For i = 1 To NChapters
'' Print chapter header across all columns:
Dim chapter = $"Chapter {i}"
tlCaption.Clear()
tlCaption.Append(chapter)
tlCaption.PerformLayout(True)
doc.Pages.Last.Graphics.DrawTextLayout(tlCaption, PointF.Empty)
'' Add outline node for the chapter:
doc.Outlines.Add(New OutlineNode(chapter, New DestinationFitV(doc.Pages.Last, Nothing)))
''
'' Clear last chapter's text and add new chapter:
tl.FirstLineIsStartOfParagraph = True
tl.LastLineIsEndOfParagraph = True
tl.Clear()
tl.Append(Util.LoremIpsum(5, 7, 9, 15, 25))
tl.PerformLayout(True)
'' Variable to hold last chapter end's bottom coord:
Dim contentBottom = 0F
'' Print the chapter:
Dim tls = New TextLayoutSplitter(tl)
While (True)
Dim tlCol0 = tls.SplitAndBalance(psas, tso)
Dim g = doc.Pages.Last.Graphics
g.DrawTextLayout(tlCol0, PointF.Empty)
g.DrawTextLayout(psas(0).TextLayout, PointF.Empty)
g.DrawTextLayout(psas(1).TextLayout, PointF.Empty)
If tls.SplitResult <> SplitResult.Split Then
'' End of chapter, find out how much height left on page for next chapter:
contentBottom = tl.ContentY + tl.ContentHeight
contentBottom = Math.Max(contentBottom, psas(0).TextLayout.ContentRectangle.Bottom)
contentBottom = Math.Max(contentBottom, psas(1).TextLayout.ContentRectangle.Bottom)
'' Done printing chapter:
Exit While
End If
'' Continue printing chapter on new page:
psas(0).MarginTop = margin
psas(1).MarginTop = margin
doc.Pages.Add()
End While
'' Next chapter - find out if we have enough space left on current page to start new chapter:
If contentBottom + captionH < pageHeight * 0.8F Then
'' Start new chapter on current page:
contentBottom += pageHeight * 0.05F
tlCaption.MarginTop = contentBottom
tl.MarginTop = contentBottom + captionH
psas(0).MarginTop = tl.MarginTop
psas(1).MarginTop = tl.MarginTop
ElseIf i < NChapters Then
'' Start new chapter on new page:
tlCaption.MarginTop = margin
tl.MarginTop = margin + captionH
psas(0).MarginTop = tl.MarginTop
psas(1).MarginTop = tl.MarginTop
doc.Pages.Add()
End If
Next
''
'' Done:
doc.Save(stream)
Return doc.Pages.Count
End Function
End Class