GraphicsInTable.cs
//
// This code is part of Document Solutions for Imaging demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GrapeCity.Documents.Layout;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;

namespace DsImagingWeb.Demos
{
    // This example shows how to draw a table with graphics drawings in cells,
    // using the GrapeCity.Documents.Drawing.TableRenderer and related classes.
    public class GraphicsInTable
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi);
            using var g = bmp.CreateGraphics(Color.White);
            DrawTable(g, pixelSize.Width, pixelSize.Height);
            return bmp;
        }

        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, 36);

            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(110);

            var cs = new CellStyle
            {
                TextAlignment = TextAlignment.Center,
                ParagraphAlignment = ParagraphAlignment.Center,
                TextFormat = new TextFormat
                {
                    Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "calibrib.ttf")),
                    FontSize = 16,
                    FontSizeInGraphicUnits = true,
                }
            };

            // Background style for displaying "Shape" with a diagonal line:
            var csCornerTopRight = new CellStyle(cs)
            {
                Background = true,
                LineWidth = 1f,
                Borders = FrameBorders.MainDiagonal,
                TextAlignment = TextAlignment.Trailing,
                ParagraphAlignment = ParagraphAlignment.Near,
                PaddingRight = 10,
                PaddingTop = 5
            };

            // Normal style for displaying "Color" at the bottom left corner of the same cell:
            var csCornerBottomLeft = new CellStyle(cs)
            {
                TextAlignment = TextAlignment.Leading,
                ParagraphAlignment = ParagraphAlignment.Far,
                PaddingLeft = 10,
                PaddingBottom = 5
            };

            // Add a background cell at the top left corner:
            ta.AddCell(csCornerTopRight, 0, 0, "Shape");

            ta.AddCell(cs, 0, 1, "Circle");
            ta.AddCell(cs, 0, 2, "Triangle");
            ta.AddCell(cs, 0, 3, "Rectangle");
            ta.AddCell(cs, 0, 4, "Oval");
            ta.AddCell(cs, 0, 5, "Square");

            // Add a normal cell at the top left corner:
            ta.AddCell(csCornerBottomLeft, 0, 0, "Color");

            ta.AddCell(cs, 1, 0, "Red");
            ta.AddCell(cs, 2, 0, "Green");
            ta.AddCell(cs, 3, 0, "Blue");
            ta.AddCell(cs, 4, 0, "Cyan");
            ta.AddCell(cs, 5, 0, "Magenta");
            ta.AddCell(cs, 6, 0, "Yellow");

            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", "calibri.ttf")),
                    FontSizeInGraphicUnits = true,
                    FontSize = 14
                },
                CreateTextLayout = (g, cs, data) =>
                {
                    var tl = g.CreateTextLayout();
                    tl.Append(((Figure)data).Title, cs.TextFormat);
                    return tl;
                },
                CustomDraw = (g, tc) =>
                {
                    // A Figure can draw itself:
                    ((Figure)tc.Data).Draw(g, tc.Width, tc.Height);
                }
            };

            ta.AddCell(1, 1, new Figure("Red Circle", Shape.Circle, Color.Red));
            ta.AddCell(1, 2, new Figure("Red Triangle", Shape.Triangle, Color.Red));
            ta.AddCell(1, 3, new Figure("Red Rectangle", Shape.Rectangle, Color.Red));
            ta.AddCell(1, 4, new Figure("Red Oval", Shape.Oval, Color.Red));
            ta.AddCell(1, 5, new Figure("Red Square", Shape.Square, Color.Red));

            ta.AddCell(2, 1, new Figure("Green Circle", Shape.Circle, Color.Green));
            ta.AddCell(2, 2, new Figure("Green Triangle", Shape.Triangle, Color.Green));
            ta.AddCell(2, 3, new Figure("Green Rectangle", Shape.Rectangle, Color.Green));
            ta.AddCell(2, 4, new Figure("Green Oval", Shape.Oval, Color.Green));
            ta.AddCell(2, 5, new Figure("Green Square", Shape.Square, Color.Green));

            ta.AddCell(3, 1, new Figure("Blue Circle", Shape.Circle, Color.Blue));
            ta.AddCell(3, 2, new Figure("Blue Triangle", Shape.Triangle, Color.Blue));
            ta.AddCell(3, 3, new Figure("Blue Rectangle", Shape.Rectangle, Color.Blue));
            ta.AddCell(3, 4, new Figure("Blue Oval", Shape.Oval, Color.Blue));
            ta.AddCell(3, 5, new Figure("Blue Square", Shape.Square, Color.Blue));

            ta.AddCell(4, 1, new Figure("Cyan Circle", Shape.Circle, Color.Cyan));
            ta.AddCell(4, 2, new Figure("Cyan Triangle", Shape.Triangle, Color.Cyan));
            ta.AddCell(4, 3, new Figure("Cyan Rectangle", Shape.Rectangle, Color.Cyan));
            ta.AddCell(4, 4, new Figure("Cyan Oval", Shape.Oval, Color.Cyan));
            ta.AddCell(4, 5, new Figure("Cyan Square", Shape.Square, Color.Cyan));

            ta.AddCell(5, 1, new Figure("Magenta Circle", Shape.Circle, Color.Magenta));
            ta.AddCell(5, 2, new Figure("Magenta Triangle", Shape.Triangle, Color.Magenta));
            ta.AddCell(5, 3, new Figure("Magenta Rectangle", Shape.Rectangle, Color.Magenta));
            ta.AddCell(5, 4, new Figure("Magenta Oval", Shape.Oval, Color.Magenta));
            ta.AddCell(5, 5, new Figure("Magenta Square", Shape.Square, Color.Magenta));

            ta.AddCell(6, 1, new Figure("Yellow Circle", Shape.Circle, Color.Yellow));
            ta.AddCell(6, 2, new Figure("Yellow Triangle", Shape.Triangle, Color.Yellow));
            ta.AddCell(6, 3, new Figure("Yellow Rectangle", Shape.Rectangle, Color.Yellow));
            ta.AddCell(6, 4, new Figure("Yellow Oval", Shape.Oval, Color.Yellow));
            ta.AddCell(6, 5, new Figure("Yellow Square", 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;
                }
            }
        }
    }
}