GraphicsTransforms.cs
//
// This code is part of GrapeCity Documents for Imaging samples.
// Copyright (c) GrapeCity, 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;

namespace GcImagingWeb.Samples
{
    // Shows how to use graphics transformations (GcGraphics.Transform property).
    public class GraphicsTransforms
    {
        private void DrawBox(string text, GcGraphics g, RectangleF box)
        {
            g.FillRectangle(box, Color.FromArgb(80, 0, 184, 204));
            g.DrawRectangle(box, Color.FromArgb(0, 193, 213), 1);
            box.Inflate(-6, -6);
            g.DrawString(text, new TextFormat()
            {
                Font = Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
                FontSize = 14,
            },
            box);
        }

        public GcBitmap GenerateImage(int pixelWidth = 1024, int pixelHeight = 1024, bool opaque = true, float dpiX = 96, float dpiY = 96)
        {
            const string baseTxt = "Text drawn at (0,36) in a 4\"x2\" box";
            var Inch = dpiX;

            var bmp = new GcBitmap(pixelWidth, pixelHeight, true, dpiX, dpiY);
            using (var g = bmp.CreateGraphics(Color.White))
            {
                var box = new RectangleF(0, 36, dpiX * 4, dpiY * 2);
                // #1:
                DrawBox($"Box 1: {baseTxt}, no transformations.", g, box);
                //
                var translate0 = Matrix3x2.CreateTranslation(Inch * 1, Inch * 4);
                var scale0 = Matrix3x2.CreateScale(0.5f);
                //
                // Transforms are applied in order from last to first.
                // #2:
                g.Transform =
                    scale0 *
                    translate0;
                DrawBox($"Box 2: {baseTxt}, translated by (1\",4\") and scaled by 0.5.", g, box);
                // #3:
                g.Transform =
                    translate0 *
                    scale0;
                DrawBox($"Box 3: {baseTxt}, scaled by 0.5 and translated by (1\",4\").", g, box);
                //
                var translate1 = Matrix3x2.CreateTranslation(Inch * 3, Inch * 5);
                var scale1 = Matrix3x2.CreateScale(0.7f);
                var rotate0 = Matrix3x2.CreateRotation((float)(-70 * Math.PI) / 180f); // 70 degrees CCW
                // #4:
                g.Transform =
                    rotate0 *
                    translate1 *
                    scale1;
                DrawBox($"Box 4: {baseTxt}, scaled by 0.7, translated by (3\",5\"), and rotated 70 degrees counterclockwise.", g, box);
                // #5:
                g.Transform =
                    Matrix3x2.CreateTranslation(36, Inch) *
                    g.Transform;
                DrawBox($"Box 5: {baseTxt}, applied current transform (Box 4), and translated by (1/2\",1\").", g, box);
                // #6:
                g.Transform =
                    // rotate0 *
                    Matrix3x2.CreateSkew((float)(-45 * Math.PI) / 180f, (float)(20 * Math.PI) / 180f) *
                    Matrix3x2.CreateTranslation(Inch * 3, Inch * 6);
                DrawBox($"Box 6: {baseTxt}, translated by (3\",6\"), and skewed -45 degrees on axis X and 20 degrees on axis Y.", g, box);
                // #7:
                g.Transform =
                    Matrix3x2.CreateRotation((float)Math.PI) *
                    Matrix3x2.CreateTranslation(bmp.Width - dpiX, bmp.Height - dpiY);
                DrawBox($"Box 7: {baseTxt}, translated by (7.5\",10\"), and rotated by 180 degrees.", g, box);
                // We can remove any transformations on a graphics like so:
                g.Transform = Matrix3x2.Identity;
                // Draw border around the whole image:
                g.DrawRectangle(new RectangleF(0, 0, bmp.Width, bmp.Height), Color.DarkSlateBlue, 4);
            }
            // Done:
            return bmp;
        }
    }
}