PushClip.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 GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;

namespace GcImagingWeb.Samples
{
    // This sample demonstrates how to use GcGraphics.PushClip/PopClip
    // methods to clip drawing operations to an arbitrary region.
    public class PushClip
    {
        public GcBitmap GenerateImage(int pixelWidth = 1024, int pixelHeight = 1024, bool opaque = true, float dpiX = 96, float dpiY = 96)
        {
            var backColor = Color.LightGray;
            var foreColor = Color.DarkRed;
            float cw = 400, ch = 300, pad = 40, bord = 4, textpad = 10;
            var clipRc = new RectangleF(pad, pixelHeight - ch - pad, cw, ch);
            var bmp = new GcBitmap(pixelWidth, pixelHeight, opaque, dpiX, dpiY);
            using (var g = bmp.CreateGraphics(backColor))
            {
                // We create a path consisting of two nested rectangles,
                // outer for the whole bitmap, inner for a text box.
                // We then use that path to create a clip region and
                // draw an image covering the whole bitmap but excluding
                // the text box:
                using (var gpath = g.CreatePath())
                {
                    gpath.BeginFigure(PointF.Empty);
                    gpath.AddLine(new PointF(pixelWidth, 0));
                    gpath.AddLine(new PointF(pixelWidth, pixelHeight));
                    gpath.AddLine(new PointF(0, pixelHeight));
                    gpath.EndFigure(FigureEnd.Closed);
                    gpath.BeginFigure(new PointF(clipRc.Left, clipRc.Top));
                    gpath.AddLine(new PointF(clipRc.Right, clipRc.Top));
                    gpath.AddLine(new PointF(clipRc.Right, clipRc.Bottom));
                    gpath.AddLine(new PointF(clipRc.Left, clipRc.Bottom));
                    gpath.EndFigure(FigureEnd.Closed);
                    using (var cliprgn = g.CreateClipRegion(gpath))
                    using (var img = Image.FromFile(Path.Combine("Resources", "ImagesBis", "clivia.jpg")))
                    {
                        g.PushClip(cliprgn);
                        g.DrawImage(
                            img,
                            new RectangleF(0, 0, pixelWidth, pixelHeight),
                            null,
                            ImageAlign.StretchImage);
                        g.PopClip(cliprgn);
                    }
                }
                // We now draw some tex inside the text box,
                // clipping to it (this overload of PushClip
                // returns an IDisposable that removes the clipping
                // when disposed):
                using (g.PushClip(clipRc))
                {
                    clipRc.Inflate(-textpad, -textpad);
                    g.DrawString(
                        Common.Util.LoremIpsum(1, 3, 4, 10, 20),
                        new TextFormat()
                        {
                            Font = Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
                            FontSize = 16,
                            ForeColor = foreColor
                        },
                        clipRc
                        );
                }
                // Draw a border around the whole image,
                // demonstrating that the clip has been removed:
                g.DrawRectangle(
                    new RectangleF(bord / 2, bord / 2, pixelWidth - bord, pixelHeight - bord),
                    new Pen(foreColor, bord));
            }
            return bmp;
        }
    }
}