TextAroundImages.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 GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' このサンプルは、矩形領域(この場合は画像)の周りに大きなテキストブロックをフロー
'' させる方法を示します。また、特定の ImageAlign を使用してページに描画された画像の
'' 実際の境界を取得する方法も示します。
Public Class TextAroundImages
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim g = doc.NewPage().Graphics
        Const fontname = "Yu Gothic"
        '' 最初のページの任意の場所に3枚の画像を描画し、
        '' 2~3ページのテキストを印刷して、最初のページの
        '' 画像を囲むようにしたいと考えています。
        '' 
        '' 画像とその矩形を取得します。すべての画像に正方形の
        '' 領域を指定しますが、元の縦横比を維持してその領域内に
        '' 配置されるので、後で画像が描かれた実際の長方形を
        '' 取得します。
        Using imgPuffins As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "puffins.jpg")),
            imgReds As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "reds.jpg")),
            imgLavender As GCDRAW.Image = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "lavender.jpg"))
            Dim rectPuffins = New RectangleF(100, 70, 180, 180)
            Dim rectReds = New RectangleF(300, 280, 180, 180)
            Dim rectLavender = New RectangleF(190, 510, 180, 180)
            '' 画像の元のアスペクト比を維持しながら、指定された領域に画像を
            '' 収めて中央に配置する ImageAlign を設定します。
            Dim ia = New ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, True, True, True, False, False)
            '' 各画像を描画し、各 DrawImage 呼び出しの出力パラメータとして長方形の配列を
            '' 提供します。これにより、画像によって実際に取得される矩形が得られます
            '' (タイル画像を処理するには配列が必要です)。
            Dim rectsPuffins As RectangleF() = Nothing
            g.DrawImage(imgPuffins, rectPuffins, Nothing, ia, rectsPuffins)
            Dim rectsReds As RectangleF() = Nothing
            g.DrawImage(imgReds, rectReds, Nothing, ia, rectsReds)
            Dim rectsLavender As RectangleF() = Nothing
            g.DrawImage(imgLavender, rectLavender, Nothing, ia, rectsLavender)
            '' テキストを出力するための TextLayout オブジェクトを作成して設定します。
            Dim tl = g.CreateTextLayout()
            tl.DefaultFormat.FontName = fontname
            tl.DefaultFormat.FontSize = 9
            tl.TextAlignment = TextAlignment.Justified
            tl.ParagraphSpacing = 72 / 8
            tl.MaxWidth = doc.PageSize.Width
            tl.MaxHeight = doc.PageSize.Height
            '' 周囲に 1/2 インチの余白。
            tl.MarginAll = 72 / 2
            '' ObjectRect は、TextLayout にフロー領域を指定するために使用される型です。
            '' イメージ矩形に基づいて ObjecRect を作成するローカル関数を設定し、
            '' いくつかのパディングを追加して、結果がよりよく見えるようにしています。
            Dim makeObjectRect As Func(Of RectangleF, ObjectRect) =
            Function(ByVal rect_)
                Return New ObjectRect(rect_.X - 6, rect_.Y - 2, rect_.Width + 12, rect_.Height + 4)
            End Function
            '' TextLayout に ObjectRect の配列を指定します。
            tl.ObjectRects = New List(Of ObjectRect)() From {
                makeObjectRect(rectsPuffins(0)),
                makeObjectRect(rectsReds(0)),
                makeObjectRect(rectsLavender(0))
            }
            '' いくつかのテキストの段落を追加します。
            tl.Append(Util.getString_ja(1, 0, 8))
            '' グリフを計算し、テキストをレイアウトします。
            tl.PerformLayout(True)
            '' ページ間のテキストの分割を制御するオプションを分割します。
            '' デフォルトのコンストラクタを使用して MaxWidth などの値を設定するか、
            '' TextLayout に基づいて TextSplitOptions を作成し、RestObjectRects を
            '' クリアすることができます。
            Dim tso = New TextSplitOptions(tl) With {
                .RestObjectRects = Nothing,
                .MinLinesInFirstParagraph = 2,
                .MinLinesInLastParagraph = 2
            }
            '' ループ内で、テキストを分割して描画します。
            While True
                '' 'rest' は、収まりきらなかったテキストを受け入れます。
                Dim rest As TextLayout = Nothing
                Dim splitResult = tl.Split(tso, rest)
                doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty)
                If splitResult <> SplitResult.Split Then
                    Exit While
                End If
                tl = rest
                '' 最初のページにのみ画像を描画します。
                tl.ObjectRects = Nothing
                doc.Pages.Add()
            End While
            ''
            '' PDF ドキュメントを保存します。
            doc.Save(stream)
            Return doc.Pages.Count
        End Using
    End Function
End Class