'' 完毕:
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Pdf.Structure
Imports GrapeCity.Documents.Pdf.MarkedContent
'' 此示例展示了如何创建带标签(结构化)的 PDF 并附加
'' 用于渲染的 TextLayout 中各个段落的标签
'' 它们放在一起,在页面之间分开。
'' 生成文档的代码与PaginatedText中使用的代码类似,
'' 但添加了标签。
'' 要查看/探索标签,请在 Adobe Acrobat Pro 中打开文档并转到
'' 查看 |导航面板|标签。
Public Class TagTextLayout
Function CreatePDF(ByVal stream As Stream) As Integer
Dim doc = New GcPdfDocument()
'' 创建一个 Part 元素,它将包含 P(段落)元素:
Dim sePart = New StructElement("Part")
doc.StructTreeRoot.Children.Add(sePart)
'' 创建并设置 TextLayout 来呈现段落:
Dim tl = New TextLayout(72)
tl.DefaultFormat.Font = StandardFonts.Times
tl.DefaultFormat.FontSize = 12
tl.FirstLineIndent = 72 / 2
tl.MaxWidth = doc.PageSize.Width
tl.MaxHeight = doc.PageSize.Height
tl.MarginAll = tl.Resolution
'' 附加文本(20 段,这样一页就放不下)
'' (请注意,TextLayout 将“\r\n”解释为段落分隔符):
''
'' 获取文本(20段):
Dim text = Util.LoremIpsum(20)
'' 为了标记各个段落,我们需要将文本拆分为段落,
'' 并使用每个段落格式的 Tag 属性(与 PDF 标签无关,
'' 它只是可以与 TextFormat 关联的任意数据)以添加
'' 段落的索引:
Dim pars = text.Split(New Char() {vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
For i = 0 To pars.Length - 1
Dim tf = New TextFormat(tl.DefaultFormat) With {.Tag = i}
tl.AppendLine(pars(i), tf)
Next
'' 布局文本:
tl.PerformLayout(True)
'' 使用分割选项来提供寡妇/孤儿控制:
Dim tso = New TextSplitOptions(tl) With {
.MinLinesInFirstParagraph = 2,
.MinLinesInLastParagraph = 2
}
'' TextLayoutHandler 实现了 ITextLayoutHandler,它
'' 允许在呈现文本时对其进行标记:
Dim tlh = New TextLayoutHandler() With {.ParentElement = sePart}
'' 在循环中,分割并渲染文本:
While True
'' 'rest' 将接受不适合的文本:
Dim rest As TextLayout = Nothing
Dim splitResult = tl.Split(tso, rest)
Dim page = doc.Pages.Add()
Dim g = page.Graphics
'' 告诉 TextLayoutHandler 我们在哪个页面:
tlh.Page = page
'' ..并将其与图形相关联:
g.TextLayoutHandler = tlh
'' 绘制适合当前页面的文本,然后前进到下一页,除非我们完成:
g.DrawTextLayout(tl, PointF.Empty)
If splitResult <> SplitResult.Split Then
Exit While
End If
tl = rest
End While
'' 将文档标记为已标记:
doc.MarkInfo.Marked = True
''
'' 完毕:
doc.Save(stream)
Return doc.Pages.Count
End Function
'' 允许在 TextLayout 呈现内容时标记内容的自定义类:
Private Class TextLayoutHandler : Implements ITextLayoutHandler
Private _tagIndex As Integer
Private _currentParagraphIndex As Integer = -1
Private _currentparagraphElement As StructElement
Public Property ParentElement As StructElement
Public Property Page As Page
Public Sub TextTagBegin(ByVal graphics As GcPdfGraphics, ByVal textLayout As TextLayout, ByVal tag As Object) Implements ITextLayoutHandler.TextTagBegin
Dim paragraphIndex As Integer
If TypeOf tag Is Integer Then
paragraphIndex = CInt(tag)
Else
paragraphIndex = -1
End If
Dim paragraphElement As StructElement
If _currentParagraphIndex = paragraphIndex Then
paragraphElement = _currentparagraphElement
Else
paragraphElement = New StructElement("P")
ParentElement.Children.Add(paragraphElement)
_currentparagraphElement = paragraphElement
_currentParagraphIndex = paragraphIndex
End If
''
graphics.BeginMarkedContent(New TagMcid("P", _tagIndex))
Dim mcil = New McrContentItemLink()
mcil.MCID = _tagIndex
mcil.Page = Page
paragraphElement.ContentItems.Add(mcil)
_tagIndex += 1
End Sub
Public Sub TextTagEnd(ByVal graphics As GcPdfGraphics, ByVal textLayout As TextLayout, ByVal tag As Object) Implements ITextLayoutHandler.TextTagEnd
graphics.EndMarkedContent()
End Sub
Public Sub AddTextArea(ByVal bounds As RectangleF) Implements ITextLayoutHandler.AddTextArea
End Sub
End Class
End Class