ScaleSvg.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 shows how to measure and scale the actual content of an SVG image.
'' It uses a sample SVG with intrinsic size larger than the actual content,
'' and content that is offset within the viewport.
Public Class ScaleSvg
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim svgPath = Path.Combine("Resources", "SvgMisc", "Smiling-Girl-offset.svg")
        Using svg = GcSvgDocument.FromFile(svgPath)
            Dim doc = New GcPdfDocument()
            Dim page = doc.NewPage()
            page.Landscape = True
            Dim g = page.Graphics
            Dim margin = g.Resolution / 4

            '' Get the actual SVG image content bounds:
            Dim contentRc = g.MeasureSvg(svg, PointF.Empty)
            '' Make sure the SVG content fits height-wise twice:
            Dim q = page.Size.Height / (contentRc.Height * 2.1F)
            contentRc.X *= q
            contentRc.Y *= q
            contentRc.Width *= q
            contentRc.Height *= q

            '' Align the actual SVG content to point (0,0):
            Dim s = svg.GetIntrinsicSize(SvgLengthUnits.Points)
            s.Width *= q
            s.Height *= q
            '' This rectangle (in points) is similar to the SVG view port.
            '' It is also scaled so that the SVG content fits twice heightwise,
            '' and the actual SVG content's top left corner is at the top left corner
            '' of the rectangle:
            Dim rc = New RectangleF(-contentRc.X, -contentRc.Y, s.Width, s.Height)

            '' Set up padding:
            Const pad As Single = 12
            rc.Offset(pad, pad)

            '' Scale down, limit number of iterations for sanity:
            Const qDown As Single = 0.8F
            Dim currRc = rc
            Dim currContentRc = contentRc
            While currRc.X + currContentRc.Right < page.Size.Width AndAlso currContentRc.Height > 8
                g.DrawSvg(svg, currRc)
                '' Scale SVG content down:
                currRc.Height *= qDown
                currRc.Width *= qDown
                currRc.Y -= (currContentRc.Top * qDown - currContentRc.Top)
                currRc.X += currContentRc.Width + currContentRc.Left - currContentRc.Left * qDown
                currContentRc.X *= qDown
                currContentRc.Y *= qDown
                currContentRc.Width *= qDown
                currContentRc.Height *= qDown
            End While

            '' Scale up:
            Const qUp As Single = 1.2F
            currRc = rc
            currContentRc = contentRc
            currRc.Offset(0, page.Size.Height - contentRc.Height - pad * 2)
            While currRc.X + currContentRc.Right < page.Size.Width
                g.DrawSvg(svg, currRc)
                '' Scale SVG content up:
                currRc.Height *= qUp
                currRc.Width *= qUp
                currRc.Y -= (currContentRc.Bottom * qUp - currContentRc.Bottom)
                currRc.X += currContentRc.Width + currContentRc.Left - currContentRc.Left * qUp
                currContentRc.X *= qUp
                currContentRc.Y *= qUp
                currContentRc.Width *= qUp
                currContentRc.Height *= qUp
            End While

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