SvgGraphicsHtmlId.cs
  1. //
  2. // This code is part of Document Solutions for Imaging demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.Drawing;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Numerics;
  11. using GrapeCity.Documents.Drawing;
  12. using GrapeCity.Documents.Text;
  13. using GrapeCity.Documents.Imaging;
  14. using GrapeCity.Documents.Svg;
  15. using DsImagingWeb.Demos.Common;
  16. using GCTEXT = GrapeCity.Documents.Text;
  17. using GCDRAW = GrapeCity.Documents.Drawing;
  18.  
  19. namespace DsImagingWeb.Demos
  20. {
  21. // This example shows how to create an SVG from scratch,
  22. // grouping visually related elements and assigning unique
  23. // HTML IDs to the groups, so that each group can be found
  24. // and manipulated from JavaScript code (e.g. some elements
  25. // of a drawing can be hidden or shown in JavaScript, etc).
  26. // This sample renders an arch similar to that in SvgGraphicsArch,
  27. // but assigns separate IDs to:
  28. // - the background;
  29. // - the arch drawing;
  30. // - measurements lines.
  31. public class SvgGraphicsHtmlId
  32. {
  33. public string DefaultMime { get => Common.Util.MimeTypes.SVG; }
  34.  
  35. public Stream GenerateImageStream(string targetMime, Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
  36. {
  37. if (targetMime != Common.Util.MimeTypes.SVG)
  38. throw new Exception("This sample only supports SVG output format.");
  39.  
  40. Color background = Color.PaleGoldenrod,
  41. line = Color.FromArgb(11, 83, 69),
  42. arc = Color.FromArgb(22, 160, 133),
  43. fill = Color.FromArgb(255, 171, 145),
  44. marks = Color.DarkGray,
  45. text = Color.Black,
  46. textBack = Color.Cornsilk;
  47.  
  48. var Inch = dpi;
  49.  
  50. // Text format for labels:
  51. var tf = new TextFormat()
  52. {
  53. Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
  54. FontSize = Inch / 6,
  55. ForeColor = text,
  56. };
  57. // Arc bounding rectangle:
  58. var rc = new RectangleF(0, 0, Inch * 4, Inch * 4.8f);
  59. // Transform to center the drawing:
  60. var transform = Matrix3x2.CreateTranslation(pixelSize.Width / 2f - rc.Width / 2, pixelSize.Height / 2f - rc.Height / 2);
  61. // A document for each layer:
  62. var svgs = new List<GcSvgDocument>();
  63.  
  64. // In a loop (from 0 to 2), draw content that belongs to the desired
  65. // current layer on a graphics, then convert that graphics to a temp GcSvgDocument
  66. // and save it in a list:
  67. for (int i = 0; i < 3; ++i)
  68. {
  69. using var g = new GcSvgGraphics(pixelSize.Width, pixelSize.Height);
  70. if (i == 0)
  71. {
  72. // Background:
  73. g.FillRectangle(new RectangleF(0, 0, g.Width, g.Height), background);
  74.  
  75. }
  76. else if (i == 1)
  77. {
  78. // Arch and text label:
  79. g.Transform = transform;
  80. DrawArch(g, rc, rc.Height * 0.3f, rc.Width * 0.08f, line, arc, fill);
  81. g.DrawString("ARCH", tf, rc, TextAlignment.Center, ParagraphAlignment.Center, false);
  82. g.Transform = Matrix3x2.Identity;
  83. }
  84. else if (i == 2)
  85. {
  86. // Measurement lines:
  87. g.Transform = transform;
  88. var w = Inch / 8;
  89. var pen = new GCDRAW.Pen(marks);
  90. // Width line/label:
  91. var txt = $"{(rc.Width / Inch):F}\"";
  92. var s = g.MeasureString(txt, tf);
  93. var d = s.Height * 1.5f;
  94. g.DrawLine(rc.Left, rc.Top - d, rc.Right, rc.Top - d, pen);
  95. g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d - w, pen);
  96. g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d + w, pen);
  97. g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d - w, pen);
  98. g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d + w, pen);
  99. var rcTxt = new RectangleF(rc.Left + rc.Width / 2 - s.Width / 2, rc.Top - d - s.Height / 2, s.Width, s.Height);
  100. rcTxt.Inflate(2, 2);
  101. g.FillRectangle(rcTxt, textBack);
  102. g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
  103. // Height line/label:
  104. txt = $"{(rc.Height / Inch):F}\"";
  105. s = g.MeasureString(txt, tf);
  106. d = s.Width;
  107. g.DrawLine(rc.Left - d, rc.Top, rc.Left - d, rc.Bottom, pen);
  108. g.DrawLine(rc.Left - d, rc.Top, rc.Left - d - w, rc.Top + w, pen);
  109. g.DrawLine(rc.Left - d, rc.Top, rc.Left - d + w, rc.Top + w, pen);
  110. g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d - w, rc.Bottom - w, pen);
  111. g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d + w, rc.Bottom - w, pen);
  112. rcTxt = new RectangleF(rc.Left - d - s.Width / 2, rc.Top + rc.Height / 2 - s.Height / 2, s.Width, s.Height);
  113. rcTxt.Inflate(2, 2);
  114. g.FillRectangle(rcTxt, textBack);
  115. g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
  116. g.Transform = Matrix3x2.Identity;
  117. }
  118. // Convert the layer to a GcSvgDocument and add it to the list:
  119. svgs.Add(g.ToSvgDocument());
  120. }
  121.  
  122. // Create the resulting SVG, add each of the temp documents
  123. // into a separate group with unique ID that can be used
  124. // to find and manipulate it:
  125. var svg = new GcSvgDocument();
  126. for (int i = 0; i < svgs.Count; ++i)
  127. {
  128. var tsvg = svgs[i];
  129. var group = new SvgGroupElement()
  130. {
  131. ID = $"myId{i}",
  132. };
  133. while (tsvg.RootSvg.Children.Count > 0)
  134. {
  135. var e = tsvg.RootSvg.Children[0];
  136. tsvg.RootSvg.Children.RemoveAt(0);
  137. group.Children.Add(e);
  138. }
  139. svg.RootSvg.Children.Add(group);
  140. }
  141. svg.RootSvg.ViewBox = new SvgViewBox(0, 0, pixelSize.Width, pixelSize.Height);
  142.  
  143. // When the resulting SVG is shown in a browser, any of the three layers
  144. // can be found and manipulated in JavaScript using the unique ID of its group.
  145. // For example, if you download the resulting SVG and open it in a browser,
  146. // you can hide the background and measurement lines by running the following
  147. // commands in the browser's console:
  148. // document.getElementById("myId0").style.display= 'none'
  149. // document.getElementById("myId2").style.display= 'none'
  150.  
  151. // Done:
  152. var ms = new MemoryStream();
  153. svg.Save(ms);
  154. ms.Seek(0, SeekOrigin.Begin);
  155. return ms;
  156. }
  157.  
  158. private void DrawArch(GcGraphics g, RectangleF rc, float harc, float wd, Color line, Color arch, Color fill)
  159. {
  160. var path = g.CreatePath();
  161. // Insides filler (start from bottom left, to clockwise):
  162. path.BeginFigure(rc.Left + wd, rc.Bottom - wd);
  163. path.AddLine(rc.Left + wd, rc.Top + harc);
  164. path.AddArc(new ArcSegment()
  165. {
  166. ArcSize = ArcSize.Small,
  167. Point = new PointF(rc.Right - wd, rc.Top + harc),
  168. RotationAngle = 0,
  169. Size = new SizeF(rc.Width / 2f - wd, harc - wd),
  170. SweepDirection = SweepDirection.Clockwise
  171. });
  172. path.AddLine(rc.Right - wd, rc.Bottom - wd);
  173. path.EndFigure(FigureEnd.Closed);
  174. g.FillPath(path, fill);
  175. path.Dispose();
  176.  
  177. // Arc outlines (start from bottom left, to clockwise):
  178. path = g.CreatePath();
  179. path.BeginFigure(rc.Left, rc.Bottom);
  180. path.AddLine(rc.Left, rc.Top + harc);
  181. path.AddLine(rc.Left + wd, rc.Top + harc);
  182. path.AddLine(rc.Left + wd, rc.Bottom - wd);
  183. path.EndFigure(FigureEnd.Closed);
  184. path.BeginFigure(rc.Left, rc.Top + harc);
  185. path.AddArc(new ArcSegment()
  186. {
  187. ArcSize = ArcSize.Small,
  188. Point = new PointF(rc.Right, rc.Top + harc),
  189. RotationAngle = 0,
  190. Size = new SizeF(rc.Width / 2f, harc),
  191. SweepDirection = SweepDirection.Clockwise
  192. });
  193. path.AddLine(rc.Right - wd, rc.Top + harc);
  194. path.AddArc(new ArcSegment()
  195. {
  196. ArcSize = ArcSize.Small,
  197. Point = new PointF(rc.Left + wd, rc.Top + harc),
  198. RotationAngle = 0,
  199. Size = new SizeF(rc.Width / 2f - wd, harc - wd),
  200. SweepDirection = SweepDirection.CounterClockwise
  201. });
  202. path.EndFigure(FigureEnd.Closed);
  203. path.BeginFigure(rc.Right, rc.Top + harc);
  204. path.AddLine(rc.Right, rc.Bottom);
  205. path.AddLine(rc.Right - wd, rc.Bottom - wd);
  206. path.AddLine(rc.Right - wd, rc.Top + harc);
  207. path.EndFigure(FigureEnd.Closed);
  208. path.BeginFigure(rc.Right, rc.Bottom);
  209. path.AddLine(rc.Left, rc.Bottom);
  210. path.AddLine(rc.Left + wd, rc.Bottom - wd);
  211. path.AddLine(rc.Right - wd, rc.Bottom - wd);
  212. path.EndFigure(FigureEnd.Closed);
  213.  
  214. g.FillPath(path, arch);
  215. g.DrawPath(path, new GCDRAW.Pen(line, 2));
  216.  
  217. path.Dispose();
  218. }
  219. }
  220. }
  221.