BalancedColumns.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
-
- '' 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
-