TextColumns.cs
// 
// このコードは、DioDocs for Imaging のサンプルの一部として提供されています。
// © MESCIUS 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;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsImagingWeb.Demos
{
    // このサンプルでは、GcBitmap 上に複数列のテキストを描画する方法を示します。
    public class TextColumns
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, true, dpi, dpi);
            using (var g = bmp.CreateGraphics(Color.White))
            {
                g.Renderer.Multithreaded = true;
                g.Renderer.SlowAntialiasing = true;

                var tl = g.CreateTextLayout();
                tl.DefaultFormat.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSerif-Regular.ttf"));

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

                // テキストを追加します(TextLayoutは "\r\n"、"\r"、"\n" を段落区切りとして解釈することにご注意ください)。
                tl.Append(Common.Util.LoremIpsum(20));
                // 列の設定を行います。
                const int colCount = 3;
                const float margin = 96 / 2; // 全体に1/2インチの余白を設定します。
                const float colGap = margin / 2; // 列間に1/4インチの間隔を設定します。
                float colWidth = (bmp.Width - margin * 2 - colGap * (colCount - 1)) / colCount;
                tl.MaxWidth = colWidth;
                tl.MaxHeight = bmp.Height - margin * 2;
                // 全体のテキストに対してグリフの計算とレイアウトを実行します。
                tl.PerformLayout(true);

                // ループ内で、現在の列に合わせてテキストを分割し、レンダリングします。
                int col = 0;
                while (true)
                {
                    // 現在のレイアウトに収まらなかった残りのテキストを保持するためのTextLayoutです。
                    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;
        }
    }
}