JapaneseText.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 JapaneseText
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            string text = "日本語(にほんご、にっぽんご)は、主として、日本列島で使用されてきた言語である。日本手話を母語とする者などを除いて、ほぼ全ての日本在住者は日本語を第一言語とする。日本国は法令上、公用語を明記していないが、事実上の公用語となっており、学校教育の「国語」で教えられる。使用者は、日本国内を主として約\uFF11億\uFF13千万人。日本語の文法体系や音韻体系を反映する手話として日本語対応手話がある。";
            var ia = new ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Top, true, true, true, false, false);

            int pageWidth = pixelSize.Width;
            int pageHeight = pixelSize.Height;

            var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, true, dpi, dpi);
            using (var g = bmp.CreateGraphics(Color.White))
            {
                g.Renderer.Multithreaded = true;

                // テキストレイアウトを設定します。
                var tl = g.CreateTextLayout();
                tl.FirstLineIndent = 18;
                tl.ParagraphSpacing = 6;
                tl.FlowDirection = FlowDirection.VerticalRightToLeft;
                tl.TextAlignment = TextAlignment.Justified;
                var tf = new TextFormat()
                {
                    Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSansJP-Regular.ttf")),
                    FontSize = 14,
                };
                // ページを埋めるためにサンプルテキストを繰り返し追加します。
                for (int i = 0; i < 12; ++i)
                {
                    tl.Append(text, tf);
                    tl.AppendLine();
                }

                // テキストを4つの水平方向に並ぶ列に配置します。
                // (このサンプルのロジックおよびコードは ArabicText のサンプル画像と同一です。)
                const int NCOLS = 4;
                var margin = 36f;
                var gap = 18f;
                var colHeight = (pageHeight - margin * 2 - gap * (NCOLS - 1)) / NCOLS;
                tl.MaxWidth = pageWidth;
                tl.MaxHeight = pageHeight;
                tl.MarginLeft = tl.MarginRight = margin;
                tl.MarginTop = margin;
                tl.MarginBottom = margin + (colHeight + gap) * (NCOLS - 1);

                // テキストが回り込むための任意の矩形領域を指定できます。
                // ここでは、いくつかの画像を描画するために3つの領域を追加します。
                tl.ObjectRects = new List<ObjectRect>()
                    {
                        new ObjectRect(pageWidth - margin - 267, margin, 267, 200),
                        new ObjectRect(margin + 100, margin + 60, 133, 100),
                        new ObjectRect(margin, pageHeight - margin - 301, 200, 301),
                    };
                using (var clouds = Common.Util.ImageFromFile(Path.Combine("Resources", "Images", "clouds.jpg")))
                    g.DrawImage(clouds, tl.ObjectRects[0].ToRectangleF(), null, ia);
                using (var firth = Common.Util.ImageFromFile(Path.Combine("Resources", "Images", "firth.jpg")))
                    g.DrawImage(firth, tl.ObjectRects[1].ToRectangleF(), null, ia);
                using (var lavender = Common.Util.ImageFromFile(Path.Combine("Resources", "Images", "lavender.jpg")))
                    g.DrawImage(lavender, tl.ObjectRects[2].ToRectangleF(), null, ia);

                // 重要な呼び出し:テキストの描画に必要なグリフを計算し、レイアウトを実行します。
                tl.PerformLayout(true);

                for (int col = 0; col < NCOLS; ++col)
                {
                    int nextcol = (col < NCOLS - 1) ? col + 1 : 0;
                    // TextSplitOptions は、残りのテキストをどのように配置するかを TextLayout.Split() に指示します。
                    // ここでは、上下の余白を更新することで列から列へと進みます。
                    var tso = new TextSplitOptions(tl)
                    {
                        RestMarginTop = margin + (colHeight + gap) * nextcol,
                        RestMarginBottom = margin + (colHeight + gap) * (NCOLS - 1 - nextcol)
                    };
                    var split = tl.Split(tso, out TextLayout rest);
                    g.DrawTextLayout(tl, PointF.Empty);
                    if (split != SplitResult.Split)
                        break;
                    tl = rest;
                }

                // 画像全体の周囲に境界線を描画します。
                g.DrawRectangle(new RectangleF(0, 0, bmp.Width, bmp.Height), Color.DarkSlateBlue, 4);
            }
            return bmp;
        }
    }
}