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

namespace DsPdfWeb.Demos
{
    // このサンプルでは、PDF を読み込み、その PDF にある A3 横向きページを A4 縦向きページ 2 つに
    // 分割した PDF に変換する方法を紹介しています。
    // 
    // 元の PDF の A3 横向きページのそれぞれについて、それを表す FormXObject を作成し、
    // 出力先の PDF に A4 縦向きページを 2 ページ追加してから、FormXObject を A4 ページの
    // それぞれのグラフィックに、左/右揃え、倍率なしでレンダリングします。
    // これにより、A3 ページの左半分を A4 ページの 1 つ目に、右半分を A4 ページの 2 つ目に
    // レンダリングすることができます。
    public class SplitA3toA4x2
    {
        public int CreatePDF(Stream stream)
        {
            // A3 と A4 のページサイズです。
            // A3 は 11.69" x 16.54" です。
            var sizeA3 = new SizeF(11.69f * 72, 16.54f * 72);
            // A4 は 8.27" x 11.60" です。
            var sizeA4 = new SizeF(8.27f * 72, 11.60f * 72);

            // A3 横向きページを含む読み込み元のサンプル PDF を作成します。
            var docA3 = new GcPdfDocument()
            {
                PageSize = sizeA3,
                Landscape = true,
            };

            // 1ページ目には、ページ全体に横向きの画像を描画します。
            var p0 = docA3.Pages.Add();
            var imgA3 = GCDRAW.Image.FromFile(Path.Combine("Resources", "Images", "aurora.jpg"));
            p0.Graphics.DrawImage(imgA3, new RectangleF(PointF.Empty, docA3.PageSize), null, GCDRAW.ImageAlign.StretchImage);

            // さらに A3 ページを追加し、ランダムな「雨にも負けず」のテキストをレンダリングします。
            var p1 = docA3.Pages.Add();
            var g = p1.Graphics;
            var tl = g.CreateTextLayout();
            tl.DefaultFormat.Font = StandardFonts.Times;
            tl.DefaultFormat.FontSize = 12;
            tl.TextAlignment = GCTEXT.TextAlignment.Justified;
            tl.FirstLineIndent = 72 / 2;
            tl.ParagraphSpacing = 72 / 8;
            // ランダムなテキストを追加します。
            tl.Append(Common.Util.getString_ja(0,0,37,15));
            // 全周 1/4 " の余白を指定します。
            const float margin = 72 / 4;
            tl.MarginAll = margin;
            var colWidth = p1.Size.Width / 2;
            tl.MaxWidth = colWidth;
            tl.MaxHeight = p1.Size.Height;
            tl.PerformLayout(true);
            // ループにて、テキストを段組み 2 つに分割してレンダリングし、必要に応じてページを追加します。
            int col = 0;
            while (true)
            {
                // 「rest」は、収まらなかったテキストを受け入れます。
                var splitResult = tl.Split(null, out GCTEXT.TextLayout rest);
                g.DrawTextLayout(tl, new PointF(col * colWidth, 0));
                if (splitResult != GCTEXT.SplitResult.Split)
                    break;
                tl = rest;
                if (++col == 2)
                {
                    docA3.Pages.Add();
                    g = docA3.Pages.Last.Graphics;
                    col = 0;
                }
            }
            // この時点で、「docA3」は A3 横向きページを持つPDFで、
            // 最初のページにはページ全体に描画された画像があり、
            // 他のページには 2 つの段組みに分割されたテキストがあります。
            //
            // このドキュメントは、必要に応じて参照用に保存することができます。
            // docA3.Save("docA3.pdf");

            // 結果として出力する PDF を A4 ページのサイズで作成します。
            var doc = new GcPdfDocument()
            {
                PageSize = sizeA4,
                Landscape = false,
            };

            // FormXObject は、画像のようにグラフィック上に描画されますが、忠実度は失われません。
            // 元の A3 ページの左半分と右半分それぞれの画像の配置を作成します。
            var iaLeft = new GCDRAW.ImageAlign(GCDRAW.ImageAlignHorz.Left, GCDRAW.ImageAlignVert.Top, false, false, true, false, false);
            var iaRight = new GCDRAW.ImageAlign(GCDRAW.ImageAlignHorz.Right, GCDRAW.ImageAlignVert.Top, false, false, true, false, false);
            foreach (var pA3 in docA3.Pages)
            {
                // 元のページを表す FormXObject を作成します。
                var fxoA3 = new FormXObject(doc, pA3);
                // 元のページの左半分/右半分をそれぞれ別ページとして出力先 PDF に描画します。
                var pLeft = doc.Pages.Add();
                pLeft.Graphics.DrawForm(fxoA3, pLeft.Bounds, pLeft.Bounds, iaLeft);
                var pRight = doc.Pages.Add();
                pRight.Graphics.DrawForm(fxoA3, pLeft.Bounds, pLeft.Bounds, iaRight);
            }

            // 終了
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}