SvgGraphicsHtmlId.cs
- //
- // 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 GrapeCity.Documents.Svg;
- using DsImagingWeb.Demos.Common;
- using GCTEXT = GrapeCity.Documents.Text;
- using GCDRAW = GrapeCity.Documents.Drawing;
-
- namespace DsImagingWeb.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.
- public class SvgGraphicsHtmlId
- {
- 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.");
-
- 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 = new TextFormat()
- {
- Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
- FontSize = Inch / 6,
- ForeColor = text,
- };
- // Arc bounding rectangle:
- var rc = new RectangleF(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 = new List<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)
- {
- using var g = new GcSvgGraphics(pixelSize.Width, pixelSize.Height);
- if (i == 0)
- {
- // Background:
- g.FillRectangle(new RectangleF(0, 0, g.Width, g.Height), background);
-
- }
- else if (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;
- }
- else if (i == 2)
- {
- // Measurement lines:
- g.Transform = transform;
- var w = Inch / 8;
- var pen = new GCDRAW.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 = 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);
- // 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 = 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);
- 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 = new GcSvgDocument();
- for (int i = 0; i < svgs.Count; ++i)
- {
- var tsvg = svgs[i];
- var group = new SvgGroupElement()
- {
- 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 = new SvgViewBox(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 = new MemoryStream();
- svg.Save(ms);
- ms.Seek(0, SeekOrigin.Begin);
- return ms;
- }
-
- private void 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();
-
- // 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();
- }
- }
- }
-