TextColumns.cs
//
// This code is part of GrapeCity Documents for Imaging samples.
// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;

namespace GcImagingWeb.Samples
{
    // This sample shows how to draw multi-column text on a GcBitmap.
    public class TextColumns
    {
        public GcBitmap GenerateImage (int pixelWidth = 1024, int pixelHeight = 1024, bool opaque = true, float dpiX = 96, float dpiY = 96)
        {
            var bmp = new GcBitmap(pixelWidth, pixelHeight, true, dpiX, dpiY);
            using (var g = bmp.CreateGraphics(Color.White))
            {
                g.Renderer.Multithreaded = true;
                g.Renderer.SlowAntialiasing = true;

                var tl = g.CreateTextLayout();
                tl.DefaultFormat.Font = Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf"));

                tl.DefaultFormat.FontSize = 12;
                tl.TextAlignment = TextAlignment.Justified;
                tl.FirstLineIndent = 96 / 2;
                tl.ParagraphSpacing = 96 / 8;

                // Add some text (note that TextLayout interprets "\r\n", "\r" and "\n" as paragraph delimiters):
                tl.Append(Common.Util.LoremIpsum(20));
                // Set up columns:
                const int colCount = 3;
                const float margin = 96 / 2; // 1/2" margins all around
                const float colGap = margin / 2; // 1/4" gap between columns
                float colWidth = (bmp.Width - margin * 2 - colGap * (colCount - 1)) / colCount;
                tl.MaxWidth = colWidth;
                tl.MaxHeight = bmp.Height - margin * 2;
                // Calculate glyphs and perform layout for the whole text:
                tl.PerformLayout(true);

                // In a loop, split and render the text in the current column:
                int col = 0;
                while (true)
                {
                    // The TextLayout that will hold the rest of the text which did not fit in the current layout:
                    var tso = new TextSplitOptions(tl)
                    {
                        MinLinesInLastParagraph = 2,
                        MinLinesInFirstParagraph = 2
                    };
                    var splitResult = tl.Split(tso, out TextLayout rest);
                    g.DrawTextLayout(tl, new PointF(margin + col * (colWidth + colGap), margin));
                    if (splitResult != SplitResult.Split)
                        break;
                    tl = rest;
                    if (++col == colCount)
                        break;
                }
            }
            return bmp;
        }
    }
}