ArabicText.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// Copyright (c) GrapeCity inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;

namespace GcPdfWeb.Samples.Basics
{
    // このサンプルは、アラビア語のテキストを段組レイアウトでレンダリングします。
    // MultiLang および JapaneseColumns も参照してください。
    public class ArabicText
    {
        readonly string text = "العربية أكبر لغات المجموعة السامية من حيث عدد المتحدثين، وإحدى أكثر اللغات انتشارًا في العالم، يتحدثها أكثر من 422 مليون نسمة،1 ويتوزع متحدثوها في المنطقة المعروفة باسم الوطن العربي، بالإضافة إلى العديد من المناطق الأخرى المجاورة كالأحواز وتركيا وتشاد ومالي والسنغالوارتيرياوللغة العربية أهمية قصوى لدى أتباع الديانة الإسلامية، فهي لغة مصدري التشريع الأساسيين في الإسلام: القرآن، والأحاديث النبوية المروية عن النبي محمد، ولا تتم الصلاة في الإسلام (وعبادات أخرى) إلا بإتقان بعض من كلمات هذه اللغة. والعربية هي أيضًا لغة طقسية رئيسية لدى عدد من الكنائس المسيحية في العالم العربي، كما كتبت بها الكثير من أهم الأعمال الدينية والفكرية اليهودية في العصور الوسطى. وأثّر انتشار الإسلام، وتأسيسه دولًا، أرتفعت مكانة اللغة العربية، وأصبحت لغة السياسة والعلم والأدب لقرون طويلة في الأراضي التي حكمها المسلمون، وأثرت العربية، تأثيرًا مباشرًا أو غير مباشر على كثير من اللغات الأخرى في العالم الإسلامي، كالتركية والفارسية والأرديةوالالبانية واللغات الأفريقية الاخرى واللغات الأوروبية مثل الروسية والإنجليزية والفرنسية والأسبانية والايطالية والألمانية.كما انها تدرس بشكل رسمى او غير رسمى في الدول الاسلامية والدول الأفريقية المحادية للوطن العربى.";

        public int CreatePDF(Stream stream)
        {
            using (var reds = Image.FromFile(Path.Combine("Resources", "Images", "reds.jpg")))
            using (var firth = Image.FromFile(Path.Combine("Resources", "Images", "firth.jpg")))
            using (var purples = Image.FromFile(Path.Combine("Resources", "Images", "purples.jpg")))
            {
                var times = Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf"));
                var ia = new ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Top, true, true, true, false, false);

                var doc = new GcPdfDocument();

                // テキストを保持およびレンダリングする TextLayout。
                var tl = new TextLayout(72);
                tl.FirstLineIndent = 18;
                tl.ParagraphSpacing = 6;
                tl.TextAlignment = TextAlignment.Justified;
                tl.AlignmentDelayToSplit = true;
                tl.RightToLeft = true;
                var tf = new TextFormat() { Font = times, FontSize = 12 };
                // テストテキストを繰り返して数ページを埋めます。
                for (int i = 0; i < 12; ++i)
                {
                    tl.Append(text, tf);
                    tl.AppendLine();
                }

                // 3列のレイアウトテキスト。
                // このサンプルのロジック/コードは、JapaneseColumns と同じです
                const int NCOLS = 3;
                var margin = 36f;
                var gap = 18f;
                var page = doc.NewPage();
                page.Landscape = true;
                var colWid = (page.Size.Width - margin * 2 - gap * (NCOLS - 1)) / NCOLS;
                tl.MaxWidth = page.Size.Width;
                tl.MaxHeight = page.Size.Height;
                tl.MarginTop = tl.MarginBottom = margin;
                tl.MarginRight = margin;
                tl.MarginLeft = margin + (colWid + gap) * (NCOLS - 1);
                // 外周にテキストがフローする任意の矩形を指定できます。
                // 今回のケースでは、3つの領域を追加していくつかの画像を描画します。
                tl.ObjectRects = new List<ObjectRect>()
                {
                    new ObjectRect(page.Size.Width - margin - 240, margin, 240, 240),
                    new ObjectRect(margin + 100, margin + 60, 133, 100),
                    new ObjectRect(margin, page.Size.Height - margin - 300, 300, 300),
                };
                // オブジェクトをイメージ領域に変換し、調整して見栄えの良いパディングを提供します。
                var rReds = tl.ObjectRects[0].ToRectangleF();
                rReds.Inflate(-4, -3);
                var rFirth = tl.ObjectRects[1].ToRectangleF();
                rFirth.Inflate(-4, -3);
                var rPurples = tl.ObjectRects[2].ToRectangleF();
                rPurples.Inflate(-4, -3);
                page.Graphics.DrawImage(reds, rReds, null, ia);
                page.Graphics.DrawImage(firth, rFirth, null, ia);
                page.Graphics.DrawImage(purples, rPurples, null, ia);

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

                bool done = false;
                // レンダリングするテキストがまだある間はループします。
                while (!done)
                {
                    for (int col = 0; col < NCOLS; ++col)
                    {
                        int nextcol = (col < NCOLS - 1) ? col + 1 : 0;
                        // TextSplitOptions は、残りのテキストのレイアウト方法を TextLayout.Split() に伝えます。
                        // 今回のケースでは、上下のマージンを更新することによって、列ごとに進めます。
                        var tso = new TextSplitOptions(tl)
                        {
                            RestMarginRight = margin + (colWid + gap) * nextcol,
                            RestMarginLeft = margin + (colWid + gap) * (NCOLS - 1 - nextcol)
                        };
                        var split = tl.Split(tso, out TextLayout rest);
                        page.Graphics.DrawTextLayout(tl, PointF.Empty);
                        if (split != SplitResult.Split)
                        {
                            done = true;
                            break;
                        }
                        tl = rest;
                    }
                    if (!done)
                    {
                        page = doc.NewPage();
                        page.Landscape = true;
                        // 最初のページに画像を描画したいだけなので、ObjectRects をクリアします。
                        if (tl.ObjectRects != null)
                        {
                            tl.ObjectRects = null;
                            // レイアウトをやり直す必要がありますが、グリフを再計算する必要はありません。
                            tl.PerformLayout(false);
                        }
                    }
                }
                // PDF ドキュメントを保存します。
                doc.Save(stream);
                return doc.Pages.Count;
            }
        }
    }
}