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

namespace DsPdfWeb.Demos
{
    // このサンプルでは、GrapeCity.Documents.Drawing.TableRenderer クラスなどを使用して、
    // セル内に図形を含むテーブルを描画する方法を紹介しています。
    public class GraphicsInTable
    {
        public int CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();
            var p = doc.Pages.Add(new SizeF(doc.PageSize.Height, doc.PageSize.Width));
            var g = p.Graphics;

            DrawTable(g, g.CanvasSize.Width, g.CanvasSize.Height);

            // PDF を保存します。
            doc.Save(stream);
            return doc.Pages.Count;
        }

        static void DrawTable(GcGraphics g, float pageWidth, float pageHeight)
        {
            var host = new LayoutHost();
            var view = host.CreateView(pageWidth, pageHeight);

            var rt = view.CreateRect();
            rt.AnchorTopLeft(null, 36, 30);

            var ta = new TableRenderer(g,
                rt, FixedTableSides.TopLeft,
                rowCount: 7, 
                columnCount: 6,
                gridLineColor: Color.Black,
                gridLineWidth: 1);

            ta.RowRects[0].SetHeight(50);
            ta.ColumnRects[0].SetWidth(80);

            var cs = new CellStyle
            {
                TextAlignment = TextAlignment.Center,
                ParagraphAlignment = ParagraphAlignment.Center,
                TextFormat = new TextFormat
                {
                    Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "ipag.ttc")),
                    FontSize = 14,
                    FontBold = true,
                    FontSizeInGraphicUnits = true,
                }
            };

            // 斜線とともに「図形」を背面で表示するためのスタイルです。
            var csCornerTopRight = new CellStyle(cs)
            {
                Background = true,
                LineWidth = 1f,
                Borders = FrameBorders.MainDiagonal,
                TextAlignment = TextAlignment.Trailing,
                ParagraphAlignment = ParagraphAlignment.Near,
                PaddingRight = 10,
                PaddingTop = 5
            };

            // 同じセルの左下に「色」を前面で表示するためのスタイルです。
            var csCornerBottomLeft = new CellStyle(cs)
            {
                TextAlignment = TextAlignment.Leading,
                ParagraphAlignment = ParagraphAlignment.Far,
                PaddingLeft = 10,
                PaddingBottom = 5
            };

            // 左上に背面でセルを追加します。
            ta.AddCell(csCornerTopRight, 0, 0, "図形");

            ta.AddCell(cs, 0, 1, "正円");
            ta.AddCell(cs, 0, 2, "三角形");
            ta.AddCell(cs, 0, 3, "長方形");
            ta.AddCell(cs, 0, 4, "楕円");
            ta.AddCell(cs, 0, 5, "正方形");

            // 左上に前面でセルを追加します。
            ta.AddCell(csCornerBottomLeft, 0, 0, "色");

            ta.AddCell(cs, 1, 0, "赤");
            ta.AddCell(cs, 2, 0, "緑");
            ta.AddCell(cs, 3, 0, "青");
            ta.AddCell(cs, 4, 0, "青緑");
            ta.AddCell(cs, 5, 0, "赤紫");
            ta.AddCell(cs, 6, 0, "黄");

            ta.DefaultCellStyle = new CellStyle
            {
                PaddingTop = 3,
                PaddingLeftRight = 20,
                PaddingBottom = 55,
                FixedWidth = false,
                TextAlignment = TextAlignment.Center,
                TextFormat = new TextFormat
                {
                    Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "ipag.ttc")),
                    FontSizeInGraphicUnits = true,
                    FontSize = 14
                },
                CreateTextLayout = (g, cs, data) =>
                {
                    var tl = g.CreateTextLayout();
                    tl.Append(((Figure)data).Title, cs.TextFormat);
                    return tl;
                },
                CustomDraw = (g, tc) =>
                {
                    // Figure クラスにてその図形自体を描画できます。
                    ((Figure)tc.Data).Draw(g, tc.Width, tc.Height);
                }
            };

            ta.AddCell(1, 1, new Figure("赤の正円", Shape.Circle, Color.Red));
            ta.AddCell(1, 2, new Figure("赤の三角形", Shape.Triangle, Color.Red));
            ta.AddCell(1, 3, new Figure("赤の長方形", Shape.Rectangle, Color.Red));
            ta.AddCell(1, 4, new Figure("赤の楕円", Shape.Oval, Color.Red));
            ta.AddCell(1, 5, new Figure("赤の正方形", Shape.Square, Color.Red));

            ta.AddCell(2, 1, new Figure("緑の正円", Shape.Circle, Color.Green));
            ta.AddCell(2, 2, new Figure("緑の三角形", Shape.Triangle, Color.Green));
            ta.AddCell(2, 3, new Figure("緑の長方形", Shape.Rectangle, Color.Green));
            ta.AddCell(2, 4, new Figure("緑の楕円", Shape.Oval, Color.Green));
            ta.AddCell(2, 5, new Figure("緑の正方形", Shape.Square, Color.Green));

            ta.AddCell(3, 1, new Figure("青の正円", Shape.Circle, Color.Blue));
            ta.AddCell(3, 2, new Figure("青の三角形", Shape.Triangle, Color.Blue));
            ta.AddCell(3, 3, new Figure("青の長方形", Shape.Rectangle, Color.Blue));
            ta.AddCell(3, 4, new Figure("青の楕円", Shape.Oval, Color.Blue));
            ta.AddCell(3, 5, new Figure("青の正方形", Shape.Square, Color.Blue));

            ta.AddCell(4, 1, new Figure("青緑の正円", Shape.Circle, Color.Cyan));
            ta.AddCell(4, 2, new Figure("青緑の三角形", Shape.Triangle, Color.Cyan));
            ta.AddCell(4, 3, new Figure("青緑の長方形", Shape.Rectangle, Color.Cyan));
            ta.AddCell(4, 4, new Figure("青緑の楕円", Shape.Oval, Color.Cyan));
            ta.AddCell(4, 5, new Figure("青緑の正方形", Shape.Square, Color.Cyan));

            ta.AddCell(5, 1, new Figure("赤紫の正円", Shape.Circle, Color.Magenta));
            ta.AddCell(5, 2, new Figure("赤紫の三角形", Shape.Triangle, Color.Magenta));
            ta.AddCell(5, 3, new Figure("赤紫の長方形", Shape.Rectangle, Color.Magenta));
            ta.AddCell(5, 4, new Figure("赤紫の楕円", Shape.Oval, Color.Magenta));
            ta.AddCell(5, 5, new Figure("赤紫の正方形", Shape.Square, Color.Magenta));

            ta.AddCell(6, 1, new Figure("黄の正円", Shape.Circle, Color.Yellow));
            ta.AddCell(6, 2, new Figure("黄の三角形", Shape.Triangle, Color.Yellow));
            ta.AddCell(6, 3, new Figure("黄の長方形", Shape.Rectangle, Color.Yellow));
            ta.AddCell(6, 4, new Figure("黄の楕円", Shape.Oval, Color.Yellow));
            ta.AddCell(6, 5, new Figure("黄の正方形", Shape.Square, Color.Yellow));

            ta.Render();
        }
        enum Shape
        {
            Circle,
            Triangle,
            Rectangle,
            Oval,
            Square
        }

        class Figure
        {
            public string Title;
            public Shape Shape;
            public Color Color;

            public Figure(string title, Shape shape, Color color)
            {
                Title = title;
                Shape = shape;
                Color = color;
            }

            public void Draw(GcGraphics g, float w, float h)
            {
                RectangleF rc;
                var pen = new GrapeCity.Documents.Drawing.Pen(Color.Black, 1);
                switch (Shape)
                {
                    case Shape.Circle:
                        rc = new RectangleF(w / 2 - 20, h - 50, 40, 40);
                        g.FillEllipse(rc, Color);
                        g.DrawEllipse(rc, pen);
                        break;
                    case Shape.Triangle:
                        var points = new PointF[]
                        {
                            new PointF(w / 2, h - 50),
                            new PointF(w / 2 + 25, h - 10),
                            new PointF(w / 2 - 25, h - 10)
                        };
                        g.FillPolygon(points, Color);
                        g.DrawPolygon(points, pen);
                        break;
                    case Shape.Rectangle:
                        rc = new RectangleF(w / 2 - 35, h - 50, 70, 40);
                        g.FillRectangle(rc, Color);
                        g.DrawRectangle(rc, pen);
                        break;
                    case Shape.Oval:
                        rc = new RectangleF(w / 2 - 35, h - 50, 70, 40);
                        g.FillEllipse(rc, Color);
                        g.DrawEllipse(rc, pen);
                        break;
                    case Shape.Square:
                        rc = new RectangleF(w / 2 - 20, h - 50, 40, 40);
                        g.FillRectangle(rc, Color);
                        g.DrawRectangle(rc, pen);
                        break;
                }
            }
        }
    }
}