SvgFontAwesome.cs
// 
// このコードは、DioDocs for PDF のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
// 
using System;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Svg;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
using GcPdfWeb.Samples.Common;

namespace GcPdfWeb.Samples
{
    // このサンプルでは、「Font Awesome」の「Free for Web」ダウンロードに含まれる SVG アイコンをレンダリングする方法を示しています。
    // また、サンプルコードでは、グリフのデフォルトカラーを変更する方法も紹介しています。
    public class SvgFontAwesome
    {
        private Random _rnd = Util.NewRandom();

        public int CreatePDF(Stream stream, int paramsIdx = 0)
        {
            return CreatePDF(stream, GetSampleParamsList()[paramsIdx]);
        }

        public int CreatePDF(Stream stream, string[] sampleParams)
        {
            // リソースから「Font Awesome」のグリフを読み込みます。
            var images = new List<(string, GcSvgDocument)>();
            var colorize = sampleParams[3] == "colorize";

            if (colorize)
            {
                foreach (var fname in Directory.GetFiles(Path.Combine("Resources", "FontAwesome"), "*.svg", SearchOption.AllDirectories))
                    images.Add((fname, GcSvgDocument.FromFile(fname)));
                // 画像の順番をランダムにします。
                images.Shuffle();
            }
            else
            {
                foreach (var fname in Directory.GetFiles(Path.Combine("Resources", "FontAwesome", sampleParams[3]), "*.svg", SearchOption.TopDirectoryOnly))
                    images.Add((fname, GcSvgDocument.FromFile(fname)));
                // 画像をファイル名でソートします。
                images.Sort(new Comparison<(string, GcSvgDocument)>((t1_, t2_) => StringComparer.OrdinalIgnoreCase.Compare(t1_.Item1, t2_.Item1)));
            }

            var doc = new GcPdfDocument();
            // キャプションのフォントとフォーマットを指定します。
            const float sMargin = 72f / 8;
            var font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"));
            var tf = new TextFormat() { Font = font, FontSize = sMargin * 0.65f };

            // レイアウト用のグリッドを設定します。
            var background = Color.White;
            var foreground = Color.Black;
            const float margin = 36;
            const int rows = 12;
            const int cols = 9;
            float gapx = 72f / 8, gapy = gapx;
            float sWidth = (doc.PageSize.Width - margin * 2 + gapx) / cols;
            float sHeight = (doc.PageSize.Height - margin * 2 + gapy) / rows;
            if (sWidth > sHeight)
            {
                gapx += sWidth - sHeight;
                sWidth = sHeight;
            }
            else
            {
                gapy += sHeight - sWidth;
                sHeight = sWidth;
            }
            var ip = new PointF(margin, margin);

            // グリッド内にすべての画像をレンダリングし、必要に応じて新しいページを追加します。
            var g = doc.NewPage().Graphics;
            for (int i = 0; i < images.Count(); ++i)
            {
                // 画像の周囲にボーダーを描画します。
                var rect = new RectangleF(ip, new SizeF(sWidth - gapx, sHeight - gapy));
                g.FillRectangle(rect, background);
                g.DrawRectangle(rect, foreground, 0.5f);
                rect.Inflate(-sMargin, -sMargin);

                // SVG を描画します。
                var svg = images[i].Item2;
                var s = svg.GetIntrinsicSize(SvgLengthUnits.Points);
                if (s.Width > 0 && s.Height > 0)
                {
                    // 画像の比率がターゲットの矩形と異なる場合、
                    // 矩形のサイズを変更し、画像を中央に配置します。
                    var qSrc = s.Width / s.Height;
                    var qTgt = rect.Width / rect.Height;
                    if (qSrc < qTgt)
                        rect.Inflate(rect.Width * (qSrc / qTgt - 1) / 2, 0);
                    else if (qSrc > qTgt)
                        rect.Inflate(0, rect.Height * (qTgt / qSrc - 1) / 2);
                }
                
                if (colorize)
                    svg.RootSvg.Fill = new SvgPaint(Color.FromArgb(_rnd.Next(256), _rnd.Next(256), _rnd.Next(256)));

                // SVGをレンダリングします。
                g.DrawSvg(svg, rect);

                // アイコンのファイル名をキャプションとして下部の余白に出力します。
                g.DrawString(Path.GetFileNameWithoutExtension(images[i].Item1), tf,
                    new RectangleF(rect.X, rect.Bottom, rect.Width, sMargin),
                    TextAlignment.Center, ParagraphAlignment.Near, false);
                ip.X += sWidth;
                if (ip.X + sWidth > doc.PageSize.Width && i < images.Count() - 1)
                {
                    ip.X = margin;
                    ip.Y += sHeight;
                    if (ip.Y + sHeight > doc.PageSize.Height)
                    {
                        g = doc.NewPage().Graphics;
                        ip.Y = margin;
                    }
                }
            }
            // PDF ドキュメントを保存します。
            doc.Save(stream);
            // PDF 保存後に画像を破棄します。
            images.ForEach(t_ => t_.Item2.Dispose());
            return doc.Pages.Count;
        }

        public static List<string[]> GetSampleParamsList()
        {
            // 配列の内容は、サンプル名、説明、情報および識別文字です。
            return new List<string[]>()
            {
                new string[] { "@b-svg/「Font Awesome」-「brands」", "「svgs/brands」ディレクトリから「Font Awesome」の SVG グリフをレンダリングする",
                    "このサンプルでは、「Font Awesome」の「Free for Web」ダウンロードの「svgs/brands」ディレクトリに含まれる SVG アイコンを、ファイル名でソートしてレンダリングします。",
                    "brands" },
                new string[] { "@b-svg/「Font Awesome」-「regular」", "「svgs/regular」ディレクトリから「Font Awesome」の SVG グリフをレンダリングする",
                    "このサンプルでは、「Font Awesome」の「Free for Web」ダウンロードの「svgs/regular」ディレクトリに含まれる SVG アイコンを、ファイル名でソートしてレンダリングします。",
                    "regular" },
                new string[] { "@b-svg/「Font Awesome」-「solid」", "「svgs/solid」ディレクトリから「Font Awesome」の SVG グリフをレンダリングする",
                    "このサンプルでは、「Font Awesome」の「Free for Web」ダウンロードの「svgs/solid」ディレクトリに含まれる SVG アイコンを、ファイル名でソートしてレンダリングします。",
                    "solid" },
                new string[] { "@b-svg/「Font Awesome」- カラー化", "「Font Awesome」の SVG グリフをランダムな順番と色でレンダリングする",
                    "このサンプルでは、「Font Awesome」の「Free for Web」ダウンロードの「svgs」ディレクトリに含まれる SVG アイコンを、順番と色をランダムに変更してレンダリングします。",
                    "colorize" },
            };
        }
    }
}