SplitA3toA4x2.cs
//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) 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
{
    // This sample shows how to convert a PDF with A3 landscape oriented pages to a PDF
    // in which each source PDF's A3 landscape page is split into two A4 portrait pages.
    // 
    // For each of the source PDF's A3 landscape pages we create a FormXObject representing it,
    // add two A4 portrait pages to the target document, and then render the FormXObject
    // onto each of the A4 pages' graphics with left and right alignment and no scaling.
    // Effectively, this renders the left half of the source A3 page on the first A4 page,
    // and the right half of it on the second A4 page.
    public class SplitA3toA4x2
    {
        public int CreatePDF(Stream stream)
        {
            // A3 and A4 page sizes:
            // A3 is 11.69" � 16.54":
            var sizeA3 = new SizeF(11.69f * 72, 16.54f * 72);
            // A4 is 8.27" x 11.60":
            var sizeA4 = new SizeF(8.27f * 72, 11.60f * 72);

            // Create a sample source PDF with A3 landscape oriented pages:
            var docA3 = new GcPdfDocument()
            {
                PageSize = sizeA3,
                Landscape = true,
            };
            
            // First page is a horizontal image filling the whole page:
            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);

            // Add a few more A3 pages as two columns of random 'lorem ipsum' text:
            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;
            // Add random text:
            tl.Append(Common.Util.LoremIpsum(37));
            // Specify 1/4" margins all around:
            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);
            // In a loop, split and render the text in a 2 column layout, adding pages as needed:
            int col = 0;
            while (true)
            {
                // 'rest' will accept the text that did not fit:
                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;
                }
            }
            // At this point, 'docA3' is a PDF with landscape oriented A3 pages,
            // the first page contains an image filling the whole page,
            // other pages contain random text in two vertical column layout.
            //
            // The document may be saved for reference if needed:
            // docA3.Save("docA3.pdf");

            // Create the resulting (target) PDF with A4 page size:
            var doc = new GcPdfDocument()
            {
                PageSize = sizeA4,
                Landscape = false,
            };

            // FormXObjects are rendered on graphics like images, but without losing fidelity.
            // We create two image alignments for the left and the right halves of the source A3 page:
            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)
            {
                // Create FormXObject representing the source page:
                var fxoA3 = new FormXObject(doc, pA3);
                // Draw its left and right halves on separate pages of the target 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);
            }

            // Done:
            doc.Save(stream);
            return doc.Pages.Count;
        }
    }
}