NumberedList.vb
'' 完毕:
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing

'' 演示如何在 GcDocs.Pdf 中将文本段落呈现为编号列表。
'' 本示例中渲染文本页面的方法取自PaginatedText
'' 样本。另请参见TextRendering。
Public Class NumberedList
    '' 封装示例中使用的页面布局常量:
    Private Structure Layout
        Public Shared Margin As Single = 72.0F
        Public Shared ListOffset As Single = 24.0F
    End Structure

    '' 在 TextLayout 中的所有段落前面添加数字的实用方法。
    Private Sub AddBullets(ByVal g As GcGraphics, ByVal pt As PointF, ByVal tl As TextLayout, ByRef itemNo As Integer)
        Dim tlBullet = g.CreateTextLayout()
        tlBullet.DefaultFormat.Font = StandardFonts.Times
        tlBullet.DefaultFormat.FontSize = 12
        For Each line In tl.Lines
            If (line.FirstLineInParagraph) Then
                tlBullet.Clear()
                tlBullet.Append($"{itemNo})")
                itemNo += 1
                tlBullet.PerformLayout(True)
                g.DrawTextLayout(tlBullet, New PointF(pt.X, pt.Y + line.Position + line.LineGap))
            End If
        Next
    End Sub

    '' 主要入口点:
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim ip = New PointF(Layout.Margin, Layout.Margin)

        '' 使用 TextLayout.MarginLeft 为列表编号/项目符号保留空间:
        Dim tl = New TextLayout(72) With {
            .MaxWidth = doc.PageSize.Width - Layout.Margin * 2,
            .MaxHeight = doc.PageSize.Height - Layout.Margin * 2,
            .ParagraphSpacing = 8,
            .MarginLeft = Layout.ListOffset
        }
        tl.DefaultFormat.Font = StandardFonts.Times

        '' 添加 20 段文本,这些文本将呈现为 20 个项目的编号列表:
        tl.Append(Util.LoremIpsum(20, 1, 6))
        '' 执行布局:
        tl.PerformLayout(True)
        '' 使用分割选项来提供寡妇/孤儿控制:
        Dim tso = New TextSplitOptions(tl)
        tso.MinLinesInFirstParagraph = 2
        tso.MinLinesInLastParagraph = 2
        '' 在循环中,分割并渲染文本(参见PaginatedText),
        '' 并添加列表编号:
        Dim itemNo = 1
        While (True)
            '' 'rest' 将接受不适合的文本:
            Dim rest As TextLayout = Nothing
            Dim splitResult = tl.Split(tso, rest)
            Dim g = doc.Pages.Add().Graphics
            g.DrawTextLayout(tl, ip)
            AddBullets(g, ip, tl, itemNo)
            If splitResult <> SplitResult.Split Then
                Exit While
            End If
            tl = rest
        End While
        ''
        '' 完毕:
        doc.Save(stream)
        Return doc.Pages.Count
    End Function
End Class