NumberedList2.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 System.Text Imports GrapeCity.Documents.Pdf Imports GrapeCity.Documents.Text Imports GrapeCity.Documents.Drawing '' Demonstrates how different styles of numbered lists can be rendered in DsPdf. '' See also NumberedList. Public Class NumberedList2 '' Encapsulate page layout constants used in the sample: Private Structure Layout '' All around page margins: Public Shared Margin As Single = 72.0F '' List offset relative to item number: Public Shared ListOffset As Single = 24.0F '' List level indent: Public Shared ListIndent As Single = 30.0F End Structure '' Define simple tree type: Private Class Node Public Sub New(ByVal txt As String) Text = txt End Sub Public Property Text As String Public Property Children As List(Of Node) = New List(Of Node)() End Class '' Renders a list of nodes as a numbered list. Private Function RenderNodes(ByRef page As Page, ByVal pt As PointF, ByVal nodes As List(Of Node), ByVal level As Integer) As PointF Dim tlBullet = page.Graphics.CreateTextLayout() tlBullet.DefaultFormat.Font = StandardFonts.Times tlBullet.MarginLeft = Layout.ListIndent * level Dim tlText = New TextLayout(72) tlText.DefaultFormat.Font = StandardFonts.Times tlText.MarginLeft = Layout.ListOffset + Layout.ListIndent * level For i = 0 To nodes.Count - 1 Dim g = page.Graphics '' Prep item text: tlText.Clear() tlText.Append(nodes(i).Text) tlText.PerformLayout(True) If pt.Y + tlText.ContentHeight > page.Size.Height - Layout.Margin Then page = page.Doc.NewPage() g = page.Graphics pt.Y = Layout.Margin End If '' Prep item number: tlBullet.Clear() tlBullet.Append(ItemIdxToString(i, level, tlBullet)) tlBullet.PerformLayout(True) '' Render item: g.DrawTextLayout(tlBullet, pt) g.DrawTextLayout(tlText, pt) '' Advance insertion point: pt.Y += tlText.ContentHeight '' Render children: If nodes(i).Children.Count > 0 Then pt = RenderNodes(page, pt, nodes(i).Children, level + 1) End If Next Return pt End Function '' Convert item index to item number representation, in a '' Arabic -> Latin letters -> Roman numbers loop. '' Roman numbers are right-aligned, others are left-aligned. Private Function ItemIdxToString(ByVal itemIdx As Integer, ByVal level As Integer, ByVal tl As TextLayout) As String Select Case (level Mod 3) Case 0 tl.MarginLeft = Layout.ListIndent * level tl.MaxWidth = Nothing tl.TextAlignment = TextAlignment.Leading Return $"{itemIdx + 1}." Case 1 tl.MarginLeft = Layout.ListIndent * level tl.MaxWidth = Nothing tl.TextAlignment = TextAlignment.Leading Return $"{ChrW(AscW("a") + itemIdx)}." Case 2 tl.MarginLeft = 0 Dim font = tl.DefaultFormat.Font tl.MaxWidth = Layout.ListIndent * level + tl.DefaultFormat.FontSize tl.TextAlignment = TextAlignment.Trailing Return $"{IntToRoman(itemIdx + 1)}." Case Else Throw New Exception("Unexpected.") End Select End Function '' From http://dotnet-snippets.com/snippet/roman-numerals/667 Private Function IntToRoman(ByVal number As Integer) As String Dim result = New StringBuilder() Dim digitsValues = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000} Dim romanDigits = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"} While number > 0 For i = digitsValues.Count() - 1 To 0 Step -1 If (number / digitsValues(i) >= 1) Then number -= digitsValues(i) result.Append(romanDigits(i).ToLower()) Exit For End If Next End While Return result.ToString() End Function '' Main entry point: Function CreatePDF(ByVal stream As Stream) As Integer Dim doc = New GcPdfDocument() Dim page = doc.NewPage() RenderNodes(page, New PointF(Layout.Margin, Layout.Margin), _arthrapods.Children, 0) '' '' Done: doc.Save(stream) Return doc.Pages.Count End Function '' Sample tree data: Private _arthrapods As New Node("Animalia Arthrapoda") With { .Children = New List(Of Node) From { New Node("Insecta") With { .Children = New List(Of Node) From { New Node("Archaeognatha") With { .Children = New List(Of Node) From { New Node("Protozoa") } }, New Node("Thysanura") With { .Children = New List(Of Node) From { New Node("Silverfish") } }, New Node("Ephemeoptera") With { .Children = New List(Of Node) From { New Node("Mafly") } }, New Node("Odonata") With { .Children = New List(Of Node) From { New Node("Dragonfly"), New Node("Azure Damzelfly"), New Node("Emerald Damzelfly") } }, New Node("Orthoptera") With { .Children = New List(Of Node) From { New Node("Grasshopper"), New Node("Cricket"), New Node("Cave Cricket") } }, New Node("Phasmatodea") With { .Children = New List(Of Node) From { New Node("Walking Stick"), New Node("Leaf Bug") } }, New Node("Mantodea") With { .Children = New List(Of Node) From { New Node("Praying Mantis") } }, New Node("Blattoeda") With { .Children = New List(Of Node) From { New Node("Cockroach") } }, New Node("Isoptera") With { .Children = New List(Of Node) From { New Node("Termite") } }, New Node("Phithiraptera") With { .Children = New List(Of Node) From { New Node("Bird Lice"), New Node("Human Lice"), New Node("Pubic Lice") } }, New Node("Hemiptera") With { .Children = New List(Of Node) From { New Node("Cicada"), New Node("Pond Skater"), New Node("Tree Hopper"), New Node("Stink Bug"), New Node("Thrip"), New Node("Alderfly") } }, New Node("Siphonatera") With { .Children = New List(Of Node) From { New Node("Flea") } } } }, New Node("Myriapoda") With { .Children = New List(Of Node) From { New Node("Chilopoda") With { .Children = New List(Of Node) From { New Node("Centipede") } }, New Node("Diplopoda") With { .Children = New List(Of Node) From { New Node("Millipede"), New Node("Pitbug") } } } }, New Node("Crustacea") With { .Children = New List(Of Node) From { New Node("Branchiopod") With { .Children = New List(Of Node) From { New Node("Brine Shrimp"), New Node("Water Flea") } }, New Node("Maxillopod") With { .Children = New List(Of Node) From { New Node("Cyclopoid"), New Node("Calgid"), New Node("Barnacles") } }, New Node("Malacostracan") With { .Children = New List(Of Node) From { New Node("Krill"), New Node("Prawn"), New Node("Shrimp"), New Node("Cancrid Crab"), New Node("Fidder Crab"), New Node("Spider Crab"), New Node("Lobster"), New Node("Hermit Crab"), New Node("Cray Fish") } } } }, New Node("Pycnogonida") With { .Children = New List(Of Node) From { New Node("Pycnogonida") With { .Children = New List(Of Node) From { New Node("Sea Spider") } } } }, New Node("Merostomata") With { .Children = New List(Of Node) From { New Node("Merostomata") With { .Children = New List(Of Node) From { New Node("Horseshoe Spider") } } } }, New Node("Arachnida") With { .Children = New List(Of Node) From { New Node("Scorpiones") With { .Children = New List(Of Node) From { New Node("Buthid"), New Node("Imperial Scorpion") } }, New Node("Pseudoscorpions") With { .Children = New List(Of Node) From { New Node("Neobisiid"), New Node("Cheliferid") } }, New Node("Solfigugae") With { .Children = New List(Of Node) From { New Node("Wind Scorpion") } }, New Node("Acari") With { .Children = New List(Of Node) From { New Node("Tick"), New Node("Mite") } }, New Node("Araneae") With { .Children = New List(Of Node) From { New Node("Crib Weaver"), New Node("Funnel-web Spider"), New Node("Funnel Weaver"), New Node("Water Spider"), New Node("Jumping Spider"), New Node("Wolf Spider"), New Node("Nursery-web Spider"), New Node("Crab Spider"), New Node("Black Widow"), New Node("Tiger Oriental Tarantula"), New Node("Mexican Red-legged Tarantula") } } } } } } End Class