//// This code is part of Document Solutions for Imaging demos.// Copyright (c) MESCIUS inc. All rights reserved.//usingSystem;usingSystem.IO;usingSystem.Drawing;usingSystem.Collections.Generic;usingSystem.Numerics;usingGrapeCity.Documents.Drawing;usingGrapeCity.Documents.Text;usingGrapeCity.Documents.Svg;usingGCTEXT = GrapeCity.Documents.Text;usingGCDRAW = GrapeCity.Documents.Drawing; namespaceDsImagingWeb.Demos{// This example shows how to create an SVG from scratch,// grouping visually related elements and assigning unique// HTML IDs to the groups, so that each group can be found// and manipulated from JavaScript code (e.g. some elements// of a drawing can be hidden or shown in JavaScript, etc). // This sample renders an arch similar to that in SvgGraphicsArch,// but assigns separate IDs to:// - the background;// - the arch drawing;// - measurements lines.publicclassSvgGraphicsHtmlId {publicstringDefaultMime { get => Common.Util.MimeTypes.SVG; } publicStreamGenerateImageStream(string targetMime, Size pixelSize, float dpi, bool opaque, string[] sampleParams = null) {if (targetMime != Common.Util.MimeTypes.SVG)thrownewException("This sample only supports SVG output format."); Color background = Color.PaleGoldenrod, line = Color.FromArgb(11, 83, 69), arc = Color.FromArgb(22, 160, 133), fill = Color.FromArgb(255, 171, 145), marks = Color.DarkGray, text = Color.Black, textBack = Color.Cornsilk; var Inch = dpi; // Text format for labels:var tf = newTextFormat() {Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSerif.ttf")),FontSize = Inch / 6,ForeColor = text, };// Arc bounding rectangle:var rc = newRectangleF(0, 0, Inch * 4, Inch * 4.8f);// Transform to center the drawing:var transform = Matrix3x2.CreateTranslation(pixelSize.Width / 2f - rc.Width / 2, pixelSize.Height / 2f - rc.Height / 2);// A document for each layer:var svgs = newList<GcSvgDocument>(); // In a loop (from 0 to 2), draw content that belongs to the desired// current layer on a graphics, then convert that graphics to a temp GcSvgDocument// and save it in a list:for (int i = 0; i < 3; ++i) {usingvar g = newGcSvgGraphics(pixelSize.Width, pixelSize.Height);if (i == 0) {// Background: g.FillRectangle(newRectangleF(0, 0, g.Width, g.Height), background); }elseif (i == 1) {// Arch and text label: g.Transform = transform;DrawArch(g, rc, rc.Height * 0.3f, rc.Width * 0.08f, line, arc, fill); g.DrawString("ARCH", tf, rc, TextAlignment.Center, ParagraphAlignment.Center, false); g.Transform = Matrix3x2.Identity; }elseif (i == 2) {// Measurement lines: g.Transform = transform;var w = Inch / 8;var pen = newGCDRAW.Pen(marks);// Width line/label: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 = newRectangleF(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);// Height line/label: 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 = newRectangleF(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); g.Transform = Matrix3x2.Identity; }// Convert the layer to a GcSvgDocument and add it to the list: svgs.Add(g.ToSvgDocument()); } // Create the resulting SVG, add each of the temp documents// into a separate group with unique ID that can be used// to find and manipulate it:var svg = newGcSvgDocument();for (int i = 0; i < svgs.Count; ++i) {var tsvg = svgs[i];var group = newSvgGroupElement() {ID = $"myId{i}", };while (tsvg.RootSvg.Children.Count > 0) {var e = tsvg.RootSvg.Children[0]; tsvg.RootSvg.Children.RemoveAt(0); group.Children.Add(e); } svg.RootSvg.Children.Add(group); } svg.RootSvg.ViewBox = newSvgViewBox(0, 0, pixelSize.Width, pixelSize.Height); // When the resulting SVG is shown in a browser, any of the three layers// can be found and manipulated in JavaScript using the unique ID of its group.// For example, if you download the resulting SVG and open it in a browser,// you can hide the background and measurement lines by running the following// commands in the browser's console:// document.getElementById("myId0").style.display= 'none' // document.getElementById("myId2").style.display= 'none' // Done:var ms = newMemoryStream(); svg.Save(ms); ms.Seek(0, SeekOrigin.Begin);return ms; } privatevoidDrawArch(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(newArcSegment() {ArcSize = ArcSize.Small,Point = newPointF(rc.Right - wd, rc.Top + harc),RotationAngle = 0,Size = newSizeF(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(); // 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(newArcSegment() {ArcSize = ArcSize.Small,Point = newPointF(rc.Right, rc.Top + harc),RotationAngle = 0,Size = newSizeF(rc.Width / 2f, harc),SweepDirection = SweepDirection.Clockwise }); path.AddLine(rc.Right - wd, rc.Top + harc); path.AddArc(newArcSegment() {ArcSize = ArcSize.Small,Point = newPointF(rc.Left + wd, rc.Top + harc),RotationAngle = 0,Size = newSizeF(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, newGCDRAW.Pen(line, 2)); path.Dispose(); } }}