SvgRandomArt.vb
''
'' This code is part of Document Solutions for Imaging demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Collections.Generic
Imports System.Linq
Imports System.Numerics
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Imaging
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 System.Random = Util.NewRandom()

    Public Function GenerateImage(
            ByVal pixelSize As Size,
            ByVal dpi As Single,
            ByVal opaque As Boolean,
            Optional ByVal sampleParams As String() = Nothing) As GcBitmap

        Using svgDoc As New GcSvgDocument()
            Dim svg = svgDoc.RootSvg
            svg.ViewBox = New SvgViewBox(0, 0, 100, 100)

            '' Random art:
            For i As Integer = 0 To rnd.Next(6, 12) - 1
                AddFigure(svg, rnd)
            Next

            '' 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:
            Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, opaque, dpi, dpi)
            Using g = bmp.CreateGraphics(Color.White)
                Dim margin As Single = dpi * 0.75F
                Dim rect As New RectangleF(margin, margin, pixelSize.Width - margin * 2, pixelSize.Width - margin * 2)
                g.DrawSvg(svgDoc, rect)
            End Using

            '' Done:
            Return bmp
        End Using
    End Function

    Private Function Next100() As Integer
        Return rnd.Next(100)
    End Function

    Private Sub AddFigure(ByVal svg As SvgSvgElement, ByVal rnd As System.Random)
        Dim pb As New SvgPathBuilder()
        Dim startX = Next100()
        Dim startY = Next100()
        pb.AddMoveTo(False, startX, startY)
        For i As Integer = 0 To rnd.Next(20, 80) - 1
            AddCurve(pb, rnd)
        Next
        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(CSng(rnd.Next(20)) / 10.0F, SvgLengthUnits.Percentage),
            .PathData = pb.ToPathData(),
            .FillOpacity = Next100() / 100.0F,
            .StrokeOpacity = Next100() / 100.0F
        })
    End Sub

    Private Sub AddCurve(ByVal pb As SvgPathBuilder, ByVal _rnd As System.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