SoftEdges.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 GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing

'' This sample demonstrates how to create a Soft Edges effect using DsImaging.
'' The Soft Edges effect deflates all non-transparent areas of an image by a specified amount,
'' then applies a Gaussian blur to make the border smooth. It is one of the effects
'' that are found in MS Word for example.
'' 
'' To achieve this effect in DsImaging, the GrayscaleBitmap.ApplyGlow() method is used
'' on the transparency mask built from the color image on which we want the soft edges to appear,
'' along with a few other simple steps as illustrated by this code.
''
'' The same GrayscaleBitmap.ApplyGlow() method is also used to achieve the Glow effect
'' as illustrated by the Glow and GlowAlt examples.
Public Class SoftEdges
    Private _font As GCTEXT.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSans.ttf"))

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

        '' Draw text and logo on a transparent bitmap:
        Dim bmp = New GcBitmap(pixelSize.Width, pixelSize.Height, False)
        bmp.Clear(Color.Transparent)
        drawTextAndLogo(bmp, pixelSize, dpi)

        '' Convert the image to a transparency mask:
        Using gs = bmp.ToGrayscaleBitmap(ColorChannel.Alpha)

            '' Apply the Soft Edges effect; while for Glow the inflation radius is positive,
            '' for Soft Edges it should be negative, -6 here (9 is the blur radius):
            gs.ApplyGlow(-6, 9)

            '' Use the resulting GrayscaleBitmap as a transparency mask when drawing the text and logo once again:
            bmp.Clear(Color.Gray)
            bmp.EnsureRendererCreated().TransparencyMaskBitmap = gs

            '' Finally, draw the text and logo once more over the prepared background:
            drawTextAndLogo(bmp, pixelSize, dpi)

            '' Done
            Return bmp
        End Using
    End Function

    '' Helper to draw text and logo
    Sub drawTextAndLogo(ByRef bmp As GcBitmap, pixelSize As Size, dpi As Single)
        DrawText(bmp.EnsureRendererCreated(), pixelSize, dpi)
        DrawLogo(bmp.EnsureRendererCreated(), New PointF(pixelSize.Width / 2, CInt(pixelSize.Height * 0.8)), pixelSize.Width / 2)
    End Sub

    Private Sub DrawText(ByVal renderer As BitmapRenderer, ByVal pixelSize As Size, ByVal dpi As Single)
        Dim f1 = New TextFormat With {
            .Font = _font,
            .FontSize = pixelSize.Height / 7,
            .ForeColor = Color.DarkOrchid,
            .FontBold = True
        }
        Dim f2 = New TextFormat(f1) With {
            .ForeColor = Color.White,
            .StrokePen = New GCDRAW.Pen(Color.DarkOrchid, 3)
        }
        Dim tl = New TextLayout(dpi) With {
            .MaxWidth = pixelSize.Width,
            .MaxHeight = pixelSize.Height,
            .ParagraphAlignment = ParagraphAlignment.Near,
            .TextAlignment = TextAlignment.Center,
            .MarginTop = dpi * 2,
            .LineSpacingScaleFactor = 0.7F
        }
        tl.AppendLine("Document", f1)
        tl.AppendLine("Solutions", f2)

        '' Draw the text:
        renderer.SlowAntialiasing = True
        renderer.DrawTextLayout(tl, 0, 0)
    End Sub

    Private Sub DrawLogo(ByVal renderer As BitmapRenderer, ByVal center As PointF, ByVal width As Single)
        Dim pb = New PathBuilder()
        pb.BeginFigure(100, 350)
        pb.AddLine(210, 310)
        Dim arc = New ArcSegment With {
            .Size = New SizeF(183, 173),
            .SweepDirection = SweepDirection.Clockwise,
            .Point = New PointF(550, 205)
        }
        pb.AddArc(arc)
        pb.AddLine(650, 170)
        pb.AddLine(680, 250)
        pb.AddLine(575, 285)
        arc.Point = New PointF(240, 390)
        pb.AddArc(arc)
        pb.AddLine(130, 430)
        pb.EndFigure(True)
        pb.Figures.Add(New EllipticFigure(New RectangleF(295, 197, 200, 190)))
        Dim gpFill = pb.ToPath()
        Dim gpStroke = gpFill.Widen(New GCDRAW.Pen(Color.Black, 20))

        '' Our 'base' size is 800 x 600 pixels:
        Dim scale As Single = width / 800
        renderer.Transform = Matrix3x2.CreateScale(scale) *
                             Matrix3x2.CreateTranslation(center.X - 400 * scale, center.Y - 300 * scale)
        renderer.FillPath(gpFill, Color.CornflowerBlue)
        renderer.FillPath(gpStroke, Color.DarkOrchid)
        renderer.Transform = Matrix3x2.Identity
    End Sub
End Class