SvgClipArt.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 System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GrapeCity.Documents.Svg;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
using DsImagingWeb.Demos.Common;

namespace DsImagingWeb.Demos
{
    // GcSvgDocument を使用して、SVG ファイルをラスタライズし、ラスター画像として描画します。
    // 本サンプルで使用している SVG のクリップアートは、freesvg.orgから提供されたものです。
    public class SvgClipArt
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            const int rows = 4;
            const int cols = 4;
            float margin = dpi / 2;
            float sMargin = margin / 4;

            // リソースフォルダから画像を読み込みます。
            List<string> fnames = new List<string>(Directory.GetFiles(Path.Combine("Resources", "SvgClipArt"), "*", SearchOption.AllDirectories));
            fnames.Shuffle();
            var images = new List<(string, GcSvgDocument)>();
            foreach (var fname in fnames.Take(rows * cols))
                images.Add((Path.GetFileName(fname), GcSvgDocument.FromFile(fname)));

            // キャプション用のフォントと書式を設定します。
            var font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSans.ttf"));
            var tf = new TextFormat() { Font = font, FontSize = sMargin * 0.65f };

            // 4x4のレイアウトグリッドを設定します。
            float gapx = margin / 4, gapy = gapx;
            float sWidth = (pixelSize.Width - margin * 2 + gapx) / cols;
            float sHeight = (pixelSize.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 bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi);
            // グリッド内に収まるようにサンプル画像を描画します。
            using var g = bmp.CreateGraphics(Color.White);
            for (int i = 0; i < images.Count(); ++i)
            {
                // 画像の周囲に境界線を描画します。
                var rect = new RectangleF(ip, new SizeF(sWidth - gapx, sHeight - gapy));
                g.FillRectangle(rect, Color.LightGray);
                g.DrawRectangle(rect, Color.Black, 0.5f);
                rect.Inflate(-sMargin, -sMargin);
                // 画像ファイル名をキャプションとして印刷します。
                g.DrawString(Path.GetFileName(images[i].Item1), tf,
                    new RectangleF(rect.X, rect.Bottom, rect.Width, sMargin),
                    TextAlignment.Center, ParagraphAlignment.Near, false);
                // 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);
                }
                // SVGをレンダリングします。
                g.DrawSvg(svg, rect);
                // 次の配置へ移動します。
                ip.X += sWidth;
                if (ip.X + sWidth > pixelSize.Width && i < images.Count() - 1)
                {
                    ip.X = margin;
                    ip.Y += sHeight;
                }
            }
            // 結果を保存した後、画像を破棄します。
            images.ForEach(t_ => t_.Item2.Dispose());
            // 画像ファイルを保存します。
            return bmp;
        }
    }
}