SvgGraphicsPicInArch.cs
C# VB
//// 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.Svg;using GCTEXT = GrapeCity.Documents.Text;using GCDRAW = GrapeCity.Documents.Drawing;
namespace DsImagingWeb.Demos{ // This example shows how to render an arch on GcSvgGraphics // using graphics paths. It also shows how a path can be used // to clip the drawing, and how to draw raster images // on GcSvgGraphics. // The arch drawing code is similar to that used in SvgGraphicsArch. public class SvgGraphicsPicInArch { public string DefaultMime { get => Common.Util.MimeTypes.SVG; }
public Stream GenerateImageStream(string targetMime, Size pixelSize, float dpi, bool opaque, string[] sampleParams = null) { if (targetMime != Common.Util.MimeTypes.SVG) throw new Exception("This sample only supports SVG output format.");
// Note that the foreground image is a PNG with some transparency: var imageFn = Path.Combine("Resources", "ImagesBis", "minerva-masked.png"); var backFn = Path.Combine("Resources", "Images", "colosseum.jpg");
Color background = Color.FromArgb(230, 153, 77), line = Color.FromArgb(102, 34, 0), arch = Color.FromArgb(147, 78, 31), archBack = Color.FromArgb(0, 191, 255), fill = Color.FromArgb(255, 171, 145), marks = Color.FromArgb(170, 62, 9), text = Color.Black, textBack = Color.Cornsilk;
var Inch = dpi; var ms = new MemoryStream(); using var g = new GcSvgGraphics(pixelSize.Width, pixelSize.Height); if (opaque) g.FillRectangle(new RectangleF(0, 0, g.Width, g.Height), background);
// Arc bounding rectangle: var rc = new RectangleF(0, 0, Inch * 5, Inch * 6.4f);
// Use transform to center all drawing: var t = g.Transform; g.Transform = Matrix3x2.CreateTranslation(g.Width / 2 - rc.Width / 2, g.Height / 2 - rc.Height / 2);
// Load and flip the foreground and background images. // NOTE that images drawn on the graphics must not be disposed // till the graphics has been converted to a GcSvgDocument: using var bmp0 = new GcBitmap(imageFn); using var bmp = bmp0.FlipRotate(FlipRotateAction.FlipHorizontal); using var backBmpT = new GcBitmap(backFn); using var backBmp = backBmpT.FlipRotate(FlipRotateAction.FlipHorizontal);
// Draw the arch and images inside: using (var innerPath = DrawArch(g, rc, rc.Height * 0.35f, rc.Width * 0.08f, line, arch, fill)) using (var clip = g.PushClip(innerPath)) { // Fill background with a color to tint the background, draw background semi-transparently, // draw foreground opaque (but it has transparent pixels): g.FillRectangle(rc, archBack); var ia = new ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, true, true, true, false, false); g.DrawImage(backBmp, rc, rc, ia, 0.7f); g.DrawImage(bmp, rc, rc, ia, 1f); }
// Add a label: var tf = new TextFormat() { Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSerif.ttf")), FontSize = Inch / 6, ForeColor = text, }; // g.DrawString("ARCH", tf, rc, TextAlignment.Center, ParagraphAlignment.Center, false);
// Measurement lines: var w = Inch / 8; var pen = new GCDRAW.Pen(marks);
var txt = $"{(rc.Width / Inch):F}\""; var s = g.MeasureString(txt, tf); var d = s.Height * 1.5f; g.DrawLine(rc.Left, rc.Top - d, rc.Right, rc.Top - d, pen); g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d - w, pen); g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d + w, pen); g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d - w, pen); g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d + w, pen);
var rcTxt = new RectangleF(rc.Left + rc.Width / 2 - s.Width / 2, rc.Top - d - s.Height / 2, s.Width, s.Height); rcTxt.Inflate(2, 2); g.FillRectangle(rcTxt, textBack); g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
txt = $"{(rc.Height / Inch):F}\""; s = g.MeasureString(txt, tf); d = s.Width; g.DrawLine(rc.Left - d, rc.Top, rc.Left - d, rc.Bottom, pen); g.DrawLine(rc.Left - d, rc.Top, rc.Left - d - w, rc.Top + w, pen); g.DrawLine(rc.Left - d, rc.Top, rc.Left - d + w, rc.Top + w, pen); g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d - w, rc.Bottom - w, pen); g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d + w, rc.Bottom - w, pen); rcTxt = new RectangleF(rc.Left - d - s.Width / 2, rc.Top + rc.Height / 2 - s.Height / 2, s.Width, s.Height); rcTxt.Inflate(2, 2); g.FillRectangle(rcTxt, textBack); g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
// Restore transform: g.Transform = t;
// Done: var svg = g.ToSvgDocument(); svg.Save(ms); ms.Seek(0, SeekOrigin.Begin); return ms; }
private IPath DrawArch(GcGraphics g, RectangleF rc, float harc, float wd, Color line, Color arch, Color fill) { var path = g.CreatePath(); // Insides filler (start from bottom left, to clockwise): path.BeginFigure(rc.Left + wd, rc.Bottom - wd); path.AddLine(rc.Left + wd, rc.Top + harc); path.AddArc(new ArcSegment() { ArcSize = ArcSize.Small, Point = new PointF(rc.Right - wd, rc.Top + harc), RotationAngle = 0, Size = new SizeF(rc.Width / 2f - wd, harc - wd), SweepDirection = SweepDirection.Clockwise }); path.AddLine(rc.Right - wd, rc.Bottom - wd); path.EndFigure(FigureEnd.Closed); g.FillPath(path, fill); // path.Dispose(); var innerPath = path;
// Arc outlines (start from bottom left, to clockwise): path = g.CreatePath(); path.BeginFigure(rc.Left, rc.Bottom); path.AddLine(rc.Left, rc.Top + harc); path.AddLine(rc.Left + wd, rc.Top + harc); path.AddLine(rc.Left + wd, rc.Bottom - wd); path.EndFigure(FigureEnd.Closed); path.BeginFigure(rc.Left, rc.Top + harc); path.AddArc(new ArcSegment() { ArcSize = ArcSize.Small, Point = new PointF(rc.Right, rc.Top + harc), RotationAngle = 0, Size = new SizeF(rc.Width / 2f, harc), SweepDirection = SweepDirection.Clockwise }); path.AddLine(rc.Right - wd, rc.Top + harc); path.AddArc(new ArcSegment() { ArcSize = ArcSize.Small, Point = new PointF(rc.Left + wd, rc.Top + harc), RotationAngle = 0, Size = new SizeF(rc.Width / 2f - wd, harc - wd), SweepDirection = SweepDirection.CounterClockwise }); path.EndFigure(FigureEnd.Closed); path.BeginFigure(rc.Right, rc.Top + harc); path.AddLine(rc.Right, rc.Bottom); path.AddLine(rc.Right - wd, rc.Bottom - wd); path.AddLine(rc.Right - wd, rc.Top + harc); path.EndFigure(FigureEnd.Closed); path.BeginFigure(rc.Right, rc.Bottom); path.AddLine(rc.Left, rc.Bottom); path.AddLine(rc.Left + wd, rc.Bottom - wd); path.AddLine(rc.Right - wd, rc.Bottom - wd); path.EndFigure(FigureEnd.Closed);
g.FillPath(path, arch); g.DrawPath(path, new GCDRAW.Pen(line, 2));
path.Dispose();
return innerPath; } }}