TagTextLayout.vb
''
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' © MESCIUS inc. All rights reserved.
''
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.getString_ja(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)
'' 分割オプションを使用して、widow/orphan の制御を提供します。
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
''
'' PDF ドキュメントを保存します。
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