SvgRandomArt.vb
''
'' This code is part of Document Solutions for PDF .NET demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Linq
Imports System.Collections.Generic
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Svg
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' This sample generates some random abstract art using the SVG path API
'' provided by GcSvgDocument.
Public Class SvgRandomArt
    Private _rnd As Random = Util.NewRandom()

    Function CreatePDF(ByVal stream As Stream) As Integer
        Using svgDoc = New GcSvgDocument()
            Dim svg = svgDoc.RootSvg
            svg.ViewBox = New SvgViewBox(0, 0, 100, 100)

            '' Random art:
            Dim i = 0
            Do While i < _rnd.Next(6, 12)
                AddFigure(svg, _rnd)
                i += 1
            Loop

            '' Border:
            svg.Children.Add(New SvgRectElement() With {
                .Width = New SvgLength(100),
                .Height = New SvgLength(100),
                .Stroke = New SvgPaint(Color.FromArgb(_rnd.Next(256), _rnd.Next(256), _rnd.Next(256))),
                .Fill = SvgPaint.None
            })
            '' Clip:
            svg.Clip = New SvgClip(New SvgLength(0), New SvgLength(0), New SvgLength(100), New SvgLength(100))

            '' Render the SVG image to a PDF:
            Dim doc = New GcPdfDocument()
            Dim page = doc.NewPage()
            Dim g = page.Graphics
            Dim s = svgDoc.GetIntrinsicSize(SvgLengthUnits.Points)

            Dim margin = 72
            Dim rect = New RectangleF(margin, margin, page.Size.Width - margin * 2, page.Size.Width - margin * 2)
            g.DrawSvg(svgDoc, rect)

            '' Done:
            doc.Save(stream)
            Return doc.Pages.Count
        End Using
    End Function

    Function Next100() As Integer
        Return _rnd.Next(100)
    End Function

    Sub AddFigure(ByVal svg As SvgSvgElement, ByVal rnd As Random)
        Dim pb = New SvgPathBuilder()
        Dim startX = Next100()
        Dim startY = Next100()
        pb.AddMoveTo(False, startX, startY)
        Dim i = 0
        Do While i < rnd.Next(20, 80)
            AddCurve(pb, rnd)
            i += 1
        Loop
        pb.AddCurveTo(False, Next100(), Next100(), Next100(), Next100(), startX, startY)

        svg.Children.Add(New SvgPathElement() With {
            .FillRule = SvgFillRule.EvenOdd,
            .Fill = New SvgPaint(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256))),
            .Stroke = New SvgPaint(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256))),
            .StrokeWidth = New SvgLength(rnd.Next(20) / 10.0F, SvgLengthUnits.Percentage),
            .PathData = pb.ToPathData(),
            .FillOpacity = Next100() / 100.0F,
            .StrokeOpacity = Next100() / 100.0F
        })
    End Sub

    Sub AddCurve(ByVal pb As SvgPathBuilder, ByVal rnd As Random)
        Select Case rnd.Next(5)
            Case 0
                pb.AddCurveTo(False, Next100(), Next100(), Next100(), Next100(), Next100(), Next100())
            Case 1
                pb.AddSmoothCurveTo(False, Next100(), Next100(), Next100(), Next100())
            Case 2
                pb.AddQuadraticBezierCurveTo(False, Next100(), Next100(), Next100(), Next100())
            Case 3
                pb.AddSmoothQuadraticBezierCurveTo(False, Next100(), Next100())
            Case 4
                pb.AddEllipticalArc(False, Next100(), Next100(), rnd.Next(360),
                    If(rnd.Next(2) = 0, GCDRAW.ArcSize.Small, GCDRAW.ArcSize.Large),
                    If(rnd.Next(2) = 0, GCDRAW.SweepDirection.Clockwise, GCDRAW.SweepDirection.CounterClockwise),
                    Next100(), Next100())
        End Select
    End Sub
End Class