SvgGraphicsPicInArch.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 render an arch on GcSvgGraphics
  22. // using graphics paths. It also shows how a path can be used
  23. // to clip the drawing, and how to draw raster images
  24. // on GcSvgGraphics.
  25. // The arch drawing code is similar to that used in SvgGraphicsArch.
  26. public class SvgGraphicsPicInArch
  27. {
  28. public string DefaultMime { get => Common.Util.MimeTypes.SVG; }
  29.  
  30. public Stream GenerateImageStream(string targetMime, Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
  31. {
  32. if (targetMime != Common.Util.MimeTypes.SVG)
  33. throw new Exception("This sample only supports SVG output format.");
  34.  
  35. // Note that the foreground image is a PNG with some transparency:
  36. var imageFn = Path.Combine("Resources", "ImagesBis", "minerva-masked.png");
  37. var backFn = Path.Combine("Resources", "Images", "colosseum.jpg");
  38.  
  39. Color background = Color.FromArgb(230, 153, 77),
  40. line = Color.FromArgb(102, 34, 0),
  41. arch = Color.FromArgb(147, 78, 31),
  42. archBack = Color.FromArgb(0, 191, 255),
  43. fill = Color.FromArgb(255, 171, 145),
  44. marks = Color.FromArgb(170, 62, 9),
  45. text = Color.Black,
  46. textBack = Color.Cornsilk;
  47.  
  48. var Inch = dpi;
  49. var ms = new MemoryStream();
  50. using var g = new GcSvgGraphics(pixelSize.Width, pixelSize.Height);
  51. if (opaque)
  52. g.FillRectangle(new RectangleF(0, 0, g.Width, g.Height), background);
  53.  
  54. // Arc bounding rectangle:
  55. var rc = new RectangleF(0, 0, Inch * 5, Inch * 6.4f);
  56.  
  57. // Use transform to center all drawing:
  58. var t = g.Transform;
  59. g.Transform = Matrix3x2.CreateTranslation(g.Width / 2 - rc.Width / 2, g.Height / 2 - rc.Height / 2);
  60.  
  61. // Load and flip the foreground and background images.
  62. // NOTE that images drawn on the graphics must not be disposed
  63. // till the graphics has been converted to a GcSvgDocument:
  64. using var bmp0 = new GcBitmap(imageFn);
  65. using var bmp = bmp0.FlipRotate(FlipRotateAction.FlipHorizontal);
  66. using var backBmpT = new GcBitmap(backFn);
  67. using var backBmp = backBmpT.FlipRotate(FlipRotateAction.FlipHorizontal);
  68.  
  69. // Draw the arch and images inside:
  70. using (var innerPath = DrawArch(g, rc, rc.Height * 0.35f, rc.Width * 0.08f, line, arch, fill))
  71. using (var clip = g.PushClip(innerPath))
  72. {
  73. // Fill background with a color to tint the background, draw background semi-transparently,
  74. // draw foreground opaque (but it has transparent pixels):
  75. g.FillRectangle(rc, archBack);
  76. var ia = new ImageAlign(ImageAlignHorz.Center, ImageAlignVert.Center, true, true, true, false, false);
  77. g.DrawImage(backBmp, rc, rc, ia, 0.7f);
  78. g.DrawImage(bmp, rc, rc, ia, 1f);
  79. }
  80.  
  81. // Add a label:
  82. var tf = new TextFormat()
  83. {
  84. Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
  85. FontSize = Inch / 6,
  86. ForeColor = text,
  87. };
  88. // g.DrawString("ARCH", tf, rc, TextAlignment.Center, ParagraphAlignment.Center, false);
  89.  
  90. // Measurement lines:
  91. var w = Inch / 8;
  92. var pen = new GCDRAW.Pen(marks);
  93.  
  94. var txt = $"{(rc.Width / Inch):F}\"";
  95. var s = g.MeasureString(txt, tf);
  96. var d = s.Height * 1.5f;
  97. g.DrawLine(rc.Left, rc.Top - d, rc.Right, rc.Top - d, pen);
  98. g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d - w, pen);
  99. g.DrawLine(rc.Left, rc.Top - d, rc.Left + w, rc.Top - d + w, pen);
  100. g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d - w, pen);
  101. g.DrawLine(rc.Right, rc.Top - d, rc.Right - w, rc.Top - d + w, pen);
  102.  
  103. var rcTxt = new RectangleF(rc.Left + rc.Width / 2 - s.Width / 2, rc.Top - d - s.Height / 2, s.Width, s.Height);
  104. rcTxt.Inflate(2, 2);
  105. g.FillRectangle(rcTxt, textBack);
  106. g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
  107.  
  108. txt = $"{(rc.Height / Inch):F}\"";
  109. s = g.MeasureString(txt, tf);
  110. d = s.Width;
  111. g.DrawLine(rc.Left - d, rc.Top, rc.Left - d, rc.Bottom, pen);
  112. g.DrawLine(rc.Left - d, rc.Top, rc.Left - d - w, rc.Top + w, pen);
  113. g.DrawLine(rc.Left - d, rc.Top, rc.Left - d + w, rc.Top + w, pen);
  114. g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d - w, rc.Bottom - w, pen);
  115. g.DrawLine(rc.Left - d, rc.Bottom, rc.Left - d + w, rc.Bottom - w, pen);
  116. rcTxt = new RectangleF(rc.Left - d - s.Width / 2, rc.Top + rc.Height / 2 - s.Height / 2, s.Width, s.Height);
  117. rcTxt.Inflate(2, 2);
  118. g.FillRectangle(rcTxt, textBack);
  119. g.DrawString(txt, tf, rcTxt, TextAlignment.Center, ParagraphAlignment.Center, false);
  120.  
  121. // Restore transform:
  122. g.Transform = t;
  123.  
  124. // Done:
  125. var svg = g.ToSvgDocument();
  126. svg.Save(ms);
  127. ms.Seek(0, SeekOrigin.Begin);
  128. return ms;
  129. }
  130.  
  131. private IPath DrawArch(GcGraphics g, RectangleF rc, float harc, float wd, Color line, Color arch, Color fill)
  132. {
  133. var path = g.CreatePath();
  134. // Insides filler (start from bottom left, to clockwise):
  135. path.BeginFigure(rc.Left + wd, rc.Bottom - wd);
  136. path.AddLine(rc.Left + wd, rc.Top + harc);
  137. path.AddArc(new ArcSegment()
  138. {
  139. ArcSize = ArcSize.Small,
  140. Point = new PointF(rc.Right - wd, rc.Top + harc),
  141. RotationAngle = 0,
  142. Size = new SizeF(rc.Width / 2f - wd, harc - wd),
  143. SweepDirection = SweepDirection.Clockwise
  144. });
  145. path.AddLine(rc.Right - wd, rc.Bottom - wd);
  146. path.EndFigure(FigureEnd.Closed);
  147. g.FillPath(path, fill);
  148. // path.Dispose();
  149. var innerPath = path;
  150.  
  151. // Arc outlines (start from bottom left, to clockwise):
  152. path = g.CreatePath();
  153. path.BeginFigure(rc.Left, rc.Bottom);
  154. path.AddLine(rc.Left, rc.Top + harc);
  155. path.AddLine(rc.Left + wd, rc.Top + harc);
  156. path.AddLine(rc.Left + wd, rc.Bottom - wd);
  157. path.EndFigure(FigureEnd.Closed);
  158. path.BeginFigure(rc.Left, rc.Top + harc);
  159. path.AddArc(new ArcSegment()
  160. {
  161. ArcSize = ArcSize.Small,
  162. Point = new PointF(rc.Right, rc.Top + harc),
  163. RotationAngle = 0,
  164. Size = new SizeF(rc.Width / 2f, harc),
  165. SweepDirection = SweepDirection.Clockwise
  166. });
  167. path.AddLine(rc.Right - wd, rc.Top + harc);
  168. path.AddArc(new ArcSegment()
  169. {
  170. ArcSize = ArcSize.Small,
  171. Point = new PointF(rc.Left + wd, rc.Top + harc),
  172. RotationAngle = 0,
  173. Size = new SizeF(rc.Width / 2f - wd, harc - wd),
  174. SweepDirection = SweepDirection.CounterClockwise
  175. });
  176. path.EndFigure(FigureEnd.Closed);
  177. path.BeginFigure(rc.Right, rc.Top + harc);
  178. path.AddLine(rc.Right, rc.Bottom);
  179. path.AddLine(rc.Right - wd, rc.Bottom - wd);
  180. path.AddLine(rc.Right - wd, rc.Top + harc);
  181. path.EndFigure(FigureEnd.Closed);
  182. path.BeginFigure(rc.Right, rc.Bottom);
  183. path.AddLine(rc.Left, rc.Bottom);
  184. path.AddLine(rc.Left + wd, rc.Bottom - wd);
  185. path.AddLine(rc.Right - wd, rc.Bottom - wd);
  186. path.EndFigure(FigureEnd.Closed);
  187.  
  188. g.FillPath(path, arch);
  189. g.DrawPath(path, new GCDRAW.Pen(line, 2));
  190.  
  191. path.Dispose();
  192.  
  193. return innerPath;
  194. }
  195. }
  196. }
  197.