SvgGraphicsHtmlId.vb
C# VB
'''' This code is part of Document Solutions for Imaging demos.'' Copyright (c) MESCIUS inc. All rights reserved.''Imports SystemImports System.IOImports System.DrawingImports System.Collections.GenericImports System.LinqImports System.NumericsImports GrapeCity.Documents.DrawingImports GrapeCity.Documents.TextImports GrapeCity.Documents.SvgImports GCTEXT = GrapeCity.Documents.TextImports GCDRAW = GrapeCity.Documents.Drawing
'' 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 ReadOnly Property DefaultMime As String Get Return Util.MimeTypes.SVG End Get End Property
Public Function GenerateImageStream( ByVal targetMime As String, ByVal pixelSize As Size, ByVal dpi As Single, ByVal opaque As Boolean, Optional ByVal sampleParams As String() = Nothing) As Stream
If targetMime <> Util.MimeTypes.SVG Then Throw New Exception("This sample only supports SVG output format.") End If
Dim background As Color = Color.PaleGoldenrod, line As Color = Color.FromArgb(11, 83, 69), arc As Color = Color.FromArgb(22, 160, 133), fill As Color = Color.FromArgb(255, 171, 145), marks As Color = Color.DarkGray, text As Color = Color.Black, textBack As Color = Color.Cornsilk
Dim Inch = dpi
'' Text format for labels: Dim tf = New TextFormat() With { .Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSerif.ttf")), .FontSize = Inch / 6, .ForeColor = text }
'' Arc bounding rectangle: Dim rc = New RectangleF(0, 0, Inch * 4, Inch * 4.8F) '' Transform to center the drawing: Dim transform = Matrix3x2.CreateTranslation(pixelSize.Width / 2.0F - rc.Width / 2, pixelSize.Height / 2.0F - rc.Height / 2) '' A document for each layer: Dim svgs = New List(Of 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 i As Integer = 0 To 2 Using g As New GcSvgGraphics(pixelSize.Width, pixelSize.Height) If i = 0 Then '' Background: g.FillRectangle(New RectangleF(0, 0, g.Width, g.Height), background) ElseIf i = 1 Then '' 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 Then '' Measurement lines: g.Transform = transform Dim w = Inch / 8 Dim pen = New GCDRAW.Pen(marks)
'' Width line/label: Dim txt = $"{(rc.Width / Inch):F}""" Dim s = g.MeasureString(txt, tf) Dim 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)
Dim 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 End If '' Convert the layer to a GcSvgDocument and add it to the list: svgs.Add(g.ToSvgDocument()) End Using Next
'' 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: Dim svg = New GcSvgDocument() For i As Integer = 0 To svgs.Count - 1 Dim tsvg = svgs(i) Dim group = New SvgGroupElement() With { .ID = $"myId{i}" } While tsvg.RootSvg.Children.Count > 0 Dim e = tsvg.RootSvg.Children(0) tsvg.RootSvg.Children.RemoveAt(0) group.Children.Add(e) End While svg.RootSvg.Children.Add(group) Next svg.RootSvg.ViewBox = New SvgViewBox(0, 0, pixelSize.Width, pixelSize.Height)
Dim ms = New MemoryStream() svg.Save(ms) ms.Seek(0, SeekOrigin.Begin) Return ms End Function
Private Sub DrawArch(g As GcGraphics, rc As RectangleF, harc As Single, wd As Single, line As Color, arch As Color, fill As Color) Dim 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() With { .ArcSize = ArcSize.Small, .Point = New PointF(rc.Right - wd, rc.Top + harc), .RotationAngle = 0, .Size = New SizeF(rc.Width / 2.0F - 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() With { .ArcSize = ArcSize.Small, .Point = New PointF(rc.Right, rc.Top + harc), .RotationAngle = 0, .Size = New SizeF(rc.Width / 2.0F, harc), .SweepDirection = SweepDirection.Clockwise }) path.AddLine(rc.Right - wd, rc.Top + harc) path.AddArc(New ArcSegment() With { .ArcSize = ArcSize.Small, .Point = New PointF(rc.Left + wd, rc.Top + harc), .RotationAngle = 0, .Size = New SizeF(rc.Width / 2.0F - 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() End SubEnd Class