PageHeaders.vb
'' 
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' © MESCIUS inc. All rights reserved.
'' 
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text

'' 左/中央/右揃えのページヘッダーとフッターを簡単に生成する方法を示します。
Public Class PageHeaders

    '' 生成されるドキュメント。
    Private _doc As GcPdfDocument

    '' ページヘッダーまたはフッターの一部を描画するユーティリティメソッドです。
    '' パラメータ:
    '' - text     :表示するのテキスト
    '' - tf       :使用するテキストの形式
    '' - pageIdx  :ページインデックス
    '' - header   :ヘッダの場合はtrue、フッターの場合はfalse
    '' - horzAlign:水平方向の配置(左揃え/中央寄せ/右揃え)
    Private Sub RenderHeader(ByVal text As String, ByVal tf As TextFormat, ByVal pageIdx As Integer, ByVal header As Boolean, ByVal horzAlign As TextAlignment)
        Dim page = _doc.Pages(pageIdx)
        Dim tl = New TextLayout(72) With {.Resolution = page.Graphics.Resolution}
        tl.MaxWidth = page.Size.Width
        tl.MaxHeight = page.Size.Height
        '' 1インチのマージン。必要に応じて調整されます。
        tl.MarginLeft = 72
        tl.MarginRight = 72
        '' 上部/下部ヘッダーの 1/3 インチの余白。必要に応じて調整されます。
        tl.MarginTop = 72 / 3
        tl.MarginBottom = tl.MarginTop
        '' 垂直方向の配置。
        tl.ParagraphAlignment = If(header, ParagraphAlignment.Near, ParagraphAlignment.Far)
        '' 水平方向の配置。
        tl.TextAlignment = horzAlign
        tl.Append(text, tf)
        '' メモ:ヘッダーまたはフッターの一部が静的である場合、対応する TextLayout オブジェクトをキャッシュすることができ、
        '' キャッシュされた TextLayout を各ページに描画することによって、いくつかのサイクルを節約できます。
        tl.PerformLayout(True)
        '' ヘッダーを(0,0)に描画します(ヘッダーは余白と配置によって配置されます)。
        page.Graphics.DrawTextLayout(tl, PointF.Empty)
    End Sub

    '' メインプログラムです。
    Function CreatePDF(ByVal stream As Stream) As Integer
        _doc = New GcPdfDocument()
        Dim page = _doc.NewPage()
        '' ページの向きを変更することに関するメモを追加します。
        Dim noteRect = Util.AddNote(
                "このサンプルでは、ページの向きを変更します。ページサイズが変化した場合でも、ヘッダーがサイズに適応できることを確認できます。",
                page)
        ''
        '' 長いテキストで TextLayout を作成して印刷します(詳細は PaginatedText を参照してください)。
        Dim tl = page.Graphics.CreateTextLayout()
        tl.DefaultFormat.FontName = "Yu Gothic"
        tl.DefaultFormat.FontSize = 12
        tl.MaxWidth = _doc.PageSize.Width
        tl.MaxHeight = _doc.PageSize.Height
        tl.MarginAll = tl.Resolution
        tl.MarginTop = noteRect.Bottom + 18
        '' サンプルテキストを追加します。
        tl.Append(Util.getString_ja(1, 0, 20))
        '' グリフを計算し、レイアウトを実行します(以下のループで PerformLayout の呼び出しも参照してください)。
        tl.PerformLayout(True)
        '' ループ内で、テキストを分割して描画します。
        While True
            Dim rest As TextLayout = Nothing
            Dim splitResult = tl.Split(Nothing, rest)
            page.Graphics.DrawTextLayout(tl, PointF.Empty)
            If splitResult <> SplitResult.Split Then
                Exit While
            End If
            tl = rest
            tl.MarginTop = tl.Resolution
            page = _doc.Pages.Add()
            '' サンプルのため、ページの向きを変更します。
            page.Landscape = Not _doc.Pages(_doc.Pages.Count - 2).Landscape
            '' 新しいページの向きを反映するためにレイアウトサイズを更新します。
            tl.MaxWidth = page.Size.Width
            tl.MaxHeight = page.Size.Height
            '' レイアウトのサイズを変更したので、再度レイアウトを実行する必要があります。
            '' ただし、グリフを再計算せずにそれを行うことができます。
            tl.PerformLayout(False)
        End While
        '' 別のループでヘッダーを描画します(これにより、 'X / Y ページ' ヘッダーを提供できます)。
        Dim tf = New TextFormat() With {.Font = StandardFonts.Helvetica, .FontSize = 10, .ForeColor = Color.Gray}
        Dim now = Util.TimeNow().ToString()
        For pageIdx = 0 To _doc.Pages.Count - 1
            RenderHeader(now, tf, pageIdx, True, TextAlignment.Leading)
            RenderHeader("簡単なページヘッダーの例", tf, pageIdx, True, TextAlignment.Center)
            RenderHeader($"Page {pageIdx + 1} of {_doc.Pages.Count}", tf, pageIdx, True, TextAlignment.Trailing)
            RenderHeader("ページフッター - 左側", tf, pageIdx, False, TextAlignment.Leading)
            RenderHeader("DioDocs for PDF", tf, pageIdx, False, TextAlignment.Center)
            RenderHeader("ページフッター - 右側", tf, pageIdx, False, TextAlignment.Trailing)
        Next
        ''
        '' PDF ドキュメントを保存します。
        _doc.Save(stream)
        Return _doc.Pages.Count
    End Function
End Class