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

namespace DsPdfWeb.Demos.Basics
{
    // 左/中央/右揃えのページヘッダーとフッターを簡単に生成する方法を示します。
    public class PageHeaders
    {
        // 生成されるドキュメント。
        private GcPdfDocument _doc;

        // ページヘッダーまたはフッターの一部を描画するユーティリティメソッドです。
        // パラメータ:
        // - text     :表示するのテキスト
        // - tf       :使用するテキストの形式
        // - pageIdx  :ページインデックス
        // - header   :ヘッダの場合はtrue、フッターの場合はfalse
        // - horzAlign:水平方向の配置(左揃え/中央寄せ/右揃え)
        private void RenderHeader(string text, TextFormat tf, int pageIdx, bool header, TextAlignment horzAlign)
        {
            var page = _doc.Pages[pageIdx];
            var tl = new TextLayout(page.Graphics.Resolution);
            tl.MaxWidth = page.Size.Width;
            tl.MaxHeight = page.Size.Height;
            // 1インチのマージン。必要に応じて調整されます。
            tl.MarginLeft = tl.MarginRight = 72;
            // 上部/下部ヘッダーの 1/3 インチの余白。必要に応じて調整されます。
            tl.MarginTop = tl.MarginBottom = 72 / 3;
            // 垂直方向の配置。
            tl.ParagraphAlignment = 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);
        }

        // メインプログラムです。
        public int CreatePDF(Stream stream)
        {
            _doc = new GcPdfDocument();
            var page = _doc.NewPage();
            // ページの向きを変更することに関するメモを追加します。
            var noteRect = Common.Util.AddNote(
                "このサンプルでは、ページの向きを変更します。ページサイズが変化した場合でも、ヘッダーがサイズに適応できることを確認できます。",
                page);
            // 長いテキストで TextLayout を作成して印刷します(詳細は PaginatedText を参照してください)。
            const string fontname = "Yu Gothic";
            var tl = page.Graphics.CreateTextLayout();
            tl.DefaultFormat.FontName = fontname;
            tl.DefaultFormat.FontSize = 10;
            tl.MaxWidth = _doc.PageSize.Width;
            tl.MaxHeight = _doc.PageSize.Height;
            tl.MarginAll = tl.Resolution;
            tl.MarginTop = noteRect.Bottom + 18;
            // サンプルテキストを追加します。
            tl.Append(Common.Util.getString_ja(1, 0, 20));
            // グリフを計算し、レイアウトを実行します(以下のループで PerformLayout の呼び出しも参照してください)。
            tl.PerformLayout(true);
            // ループ内で、テキストを分割して描画します。
            while (true)
            {
                var splitResult = tl.Split(null, out TextLayout rest);
                page.Graphics.DrawTextLayout(tl, PointF.Empty);
                if (splitResult != SplitResult.Split)
                    break;
                tl = rest;
                tl.MarginTop = tl.Resolution;
                page = _doc.Pages.Add();
                // サンプルのため、ページの向きを変更します。
                page.Landscape = !_doc.Pages[_doc.Pages.Count - 2].Landscape;
                // 新しいページの向きを反映するためにレイアウトサイズを更新します。
                tl.MaxWidth = page.Size.Width;
                tl.MaxHeight = page.Size.Height;
                // レイアウトのサイズを変更したので、再度レイアウトを実行する必要があります。
                // ただし、グリフを再計算せずにそれを行うことができます。
                tl.PerformLayout(false);
            }
            // 別のループでヘッダーを描画します(これにより、 'X / Y ページ' ヘッダーを提供できます)。
            var tf = new TextFormat() { Font = StandardFonts.Helvetica, FontSize = 10, ForeColor = Color.Gray };
            var now = Common.Util.TimeNow().ToString();
            for (int pageIdx = 0; pageIdx < _doc.Pages.Count; ++pageIdx)
            {
                RenderHeader(now, tf, pageIdx, true, TextAlignment.Leading);
                RenderHeader("簡単なページヘッダーの例", tf, pageIdx, true, TextAlignment.Center);
                RenderHeader($"{pageIdx + 1} / {_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);
            }
            // PDF ドキュメントを保存します。
            _doc.Save(stream);
            return _doc.Pages.Count;
        }
    }
}