//
// 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.Collections.Generic;
using System.Linq;
using System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
namespace DsImagingWeb.Demos
{
// This example shows how to draw a window with a solid frame
// and four semi-transparent colored window panes,
// floating above a solid brick wall with some text written on it,
// and casting a semi-transparent colored shadow on the wall.
public class TransparentShadow
{
private GCTEXT.Font _font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "segoesc.ttf"));
public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
{
// A temporary bitmap to hold the shadow:
using var shadow = new GcBitmap(pixelSize.Width, pixelSize.Height, false);
// Draw the window on the shadow bitmap; the offsetX/offsetY (64/82)
// account for the shadow's offset relative to the floating window
// that will be drawn later:
using (var g = shadow.CreateGraphics(Color.Transparent))
DrawWindow(g, pixelSize, 64, 82);
// Create a shadow without blur in 'shadowTemp' and blend it with the main shadow bitmap
// in order to render colored shadows of the semi-transparent window panes:
using (var gs = shadow.ToGrayscaleBitmap(ColorChannel.Alpha))
using (var shadowTemp = gs.ToShadowBitmap(Color.DarkSlateGray))
shadow.AlphaBlend(shadowTemp, 0, 0);
// At this point 'shadow' contains opaque colored shadow without blur,
// we apply the blur effect and make it semi-transparent:
shadow.ApplyEffect(GaussianBlurEffect.Get(29));
shadow.ApplyEffect(OpacityEffect.Get(0.85f));
// Prepare the brick wall image:
var wall = new GcBitmap(pixelSize.Width, pixelSize.Height, true);
using (var g = wall.CreateGraphics(Color.DarkSalmon))
DrawWall(g, pixelSize);
// Blend the shadow with the wall:
wall.AlphaBlend(shadow, 0, 0);
// Finally draw the window floating in front of the wall:
using (var g = wall.CreateGraphics())
DrawWindow(g, pixelSize, 0, 0);
// Done
return wall;
}
// Draw a window with four colored semi-transparent panes:
void DrawWindow(GcGraphics g, Size pixelSize, float offsetX, float offsetY)
{
var w = pixelSize.Width * 0.4f;
var h = pixelSize.Height * 0.5f;
var x = pixelSize.Width / 2 - w / 2;
var y = pixelSize.Height / 2 - h / 2;
g.Transform = Matrix3x2.CreateTranslation(offsetX, offsetY);
var wnd = new RectangleF(x, y, w, h);
var winHalf = new SizeF(wnd.Width / 2, wnd.Height / 2);
var glassTL = Color.FromArgb(unchecked((int)0x70FF4600));
var glassTR = Color.FromArgb(unchecked((int)0x70A5FF00));
var glassBL = Color.FromArgb(unchecked((int)0x70007BFF));
var glassBR = Color.FromArgb(unchecked((int)0x70FFCD00));
g.FillRectangle(new RectangleF(wnd.Location, winHalf), glassTL);
g.FillRectangle(new RectangleF(new PointF(wnd.X + wnd.Width / 2, wnd.Y), winHalf), glassTR);
g.FillRectangle(new RectangleF(new PointF(wnd.X, wnd.Y + wnd.Height / 2), winHalf), glassBL);
g.FillRectangle(new RectangleF(new PointF(wnd.X + wnd.Width / 2, wnd.Y + wnd.Height / 2), winHalf), glassBR);
var outline = Color.DarkSlateGray;
g.DrawRectangle(wnd, new GCDRAW.Pen(outline, 34));
g.DrawLine(wnd.Left, wnd.Top + wnd.Height / 2, wnd.Right, wnd.Top + wnd.Height / 2, outline, 24);
g.DrawLine(wnd.Left + wnd.Width / 2, wnd.Top, wnd.Left + wnd.Width / 2, wnd.Bottom, outline, 24);
var frame = Color.LightGoldenrodYellow;
g.DrawRectangle(wnd, new GCDRAW.Pen(frame, 30));
g.DrawLine(wnd.Left, wnd.Top + wnd.Height / 2, wnd.Right, wnd.Top + wnd.Height / 2, frame, 20);
g.DrawLine(wnd.Left + wnd.Width / 2, wnd.Top, wnd.Left + wnd.Width / 2, wnd.Bottom, frame, 20);
g.Transform = Matrix3x2.Identity;
}
// Draw a brick wall with a white text:
void DrawWall(GcGraphics g, Size pixelSize)
{
// The brick pattern:
var brick = new Size(112, 44);
var pen = new GCDRAW.Pen(Color.DimGray, 2);
var off = brick.Width / 2;
for (int y = -brick.Height / 3; y < pixelSize.Height; y += brick.Height)
{
for (int x = off + brick.Width / 3; x < pixelSize.Width; x += brick.Width)
{
g.DrawLine(x, y, x, y + brick.Height, pen);
}
off = off == 0 ? brick.Width / 2 : 0;
g.DrawLine(0, y, pixelSize.Width, y, pen);
}
// Graffiti-like white text (overlay blend mode is used to visually preserve the joints):
var tl = g.CreateTextLayout();
tl.MaxWidth = pixelSize.Width;
tl.MaxHeight = pixelSize.Height;
tl.ParagraphAlignment = ParagraphAlignment.Center;
tl.TextAlignment = TextAlignment.Center;
tl.DefaultFormat.Font = _font;
tl.DefaultFormat.FontSize = 270;
tl.DefaultFormat.ForeColor = Color.White;
tl.ParagraphSpacing = -120;
tl.Append("The\nWall");
g.BlendMode = BlendMode.Overlay;
g.DrawTextLayout(tl, Point.Empty);
g.BlendMode = BlendMode.Normal;
}
}
}