ColorSpectrum.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.Collections.Generic;
using System.Linq;
using System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;

namespace GcImagingWeb.Samples
{
    // This sample shows how a color spectrum with fall offs from fully saturated
    // colors to white and black can be easily created using linear gradient brushes
    // and GcBitmap.Renderer.TransparencyMaskBitmap.
    public class ColorSpectrum
    {
        public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
        {
            // Color spectrum gradient brush:
            var spec = new LinearGradientBrush(Color.Red, Color.Red);
            var step = 1f / 6f;
            spec.GradientStops = new GradientStop[]
            {
                new GradientStop(Color.Yellow, step),
                new GradientStop(Color.Green, step * 2),
                new GradientStop(Color.Cyan, step * 3),
                new GradientStop(Color.Blue, step * 4),
                new GradientStop(Color.Magenta, step * 5),
            };

            // Create the spectrum in a separate temp bitmap:
            var spectrumSz = new Size(pixelSize.Width, (int)(pixelSize.Height * 0.75f));
            // Falloff brush and mask:
            using var tbmp = new GcBitmap(spectrumSz.Width, spectrumSz.Height, true);
            using var tgfx = tbmp.CreateGraphics();
            // Black is opaque, White transparent:
            var falloff = new LinearGradientBrush(Color.Black, PointF.Empty, Color.Black, new PointF(0, 1));
            // Additional gray stops provide a more gradual and pleasing appearance:
            falloff.GradientStops = new GradientStop[]
            {
                new GradientStop(Color.LightGray, 0.35f),
                new GradientStop(Color.White, 0.5f),
                new GradientStop(Color.LightGray, 0.65f)
            };
            // Fill the mask with the gradient that will define the transparency:
            tgfx.FillRectangle(new RectangleF(0, 0, tbmp.Width, tbmp.Height), falloff);
            // Convert mask to grayscale for use as the transparency mask:
            using var mask = tbmp.ToGrayscaleBitmap();
            
            // Reuse the original mask bitmap;
            // Fill it with a gradient from white at the top to black at the bottom:
            var grad = new LinearGradientBrush(Color.White, PointF.Empty, Color.Black, new PointF(0, 1));
            tgfx.FillRectangle(new RectangleF(0, 0, spectrumSz.Width, spectrumSz.Height), grad);

            // Add transparency mask and draw the gradient:
            tbmp.Renderer.TransparencyMaskBitmap = mask;
            tgfx.FillRectangle(new RectangleF(PointF.Empty, spectrumSz), spec);

            // Copy spectrum to the target bitmap:
            var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, true, dpi, dpi);
            bmp.BitBlt(tbmp, 0, 0);

            // Add some explanatory texts below the spectrum:
            var g = bmp.CreateGraphics();
            var rc = new RectangleF(0, spectrumSz.Height, spectrumSz.Width, bmp.PixelHeight - spectrumSz.Height);
            var tf = new TextFormat()
            {
                Font = Font.FromFile(Path.Combine("Resources", "Fonts", "courbd.ttf")),
                FontSize = 14,
            };
            g.FillRectangle(rc, Color.LightGray);
            g.DrawString(
                "The color spectrum is drawn using a horizontal linear gradient brush with 7 stops:\n" +
                "Red - Yellow - Green - Cyan - Blue - Magenta - Red.\n" +
                "The background is filled with a vertical gradient from white to black. " +
                "A TransparencyMaskBitmap with a vertical gradient that changes from 0 " +
                "(opaque) to 1 (transparent) back to 0 (opaque) provides falloffs " +
                "from spectrum colors in the center up to white and down to black backgrounds.",
                tf, rc, TextAlignment.Center, ParagraphAlignment.Center);

            return bmp;
        }
    }
}