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

Public Class AllBlendModes
    Public Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim page = doc.NewPage()
        Dim g = page.Graphics

        Dim iorchid = GCDRAW.Image.FromFile(Path.Combine("Resources", "ImagesBis", "orchid.jpg"))
        Dim ispectr = GCDRAW.Image.FromFile(Path.Combine("Resources", "ImagesBis", "spectrum-pastel-500x500.png"))

        Const margin As Integer = 36
        Const NCOLS As Integer = 4
        Dim w = CInt((page.Size.Width - margin * 2) / NCOLS)
        Dim h = (iorchid.Height * w) \ iorchid.Width

        ' Text layout for captions:
        Dim tl = g.CreateTextLayout()
        tl.DefaultFormat.Font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSansMono-Regular.ttf"))
        tl.DefaultFormat.FontSize = 12
        tl.ParagraphAlignment = ParagraphAlignment.Center
        tl.TextAlignment = TextAlignment.Center
        tl.MaxWidth = w
        tl.MaxHeight = h
        tl.MarginTop = h - g.MeasureString("QWERTY", tl.DefaultFormat).Height * 1.4F

        Dim row As Integer = 0
        Dim col As Integer = 0
        Dim dy As Integer = 0
        Dim x As Integer = 0
        Dim y As Integer = 0
        Dim r As RectangleF = Nothing
        Dim rc As RectangleF = Nothing
        Dim blendMode As BlendMode = BlendMode.Normal
        Dim iback As GCDRAW.Image = Nothing
        Dim ifore As GCDRAW.Image = Nothing

        ' Render all blending modes in a grid:
        Dim modes = System.Enum.GetValues(GetType(BlendMode))
        For i As Integer = 0 To 1
            row = 0
            col = 0
            If i = 0 Then
                iback = ispectr
                ifore = iorchid
                Dim trc1 = Util.AddNote(
                    "Below are tiles drawn by composing two images (a spectrum and an orchid) using the " &
                    "different blend modes supported by DsPdf. " &
                    "First the spectrum image is drawn normally, then it is overlaid by the orchid image " &
                    "drawn in a supported blend mode. The blend mode name is shown below each tile." &
                    vbLf &
                    "Tiles on the second page are composed of the same images but drawn in reverse order: " &
                    "the orchid is drawn normally, the spectrum is blended with it using the different modes." &
                    vbLf &
                    "Note that the current blend mode affects not only images but any drawing on a GcGraphics. " &
                    "The blend mode names on the 2nd page illustrate this.",
                    page)
                dy = CInt(Fix(trc1.Bottom))
            Else
                iback = iorchid
                ifore = ispectr
                page = doc.Pages.Add()
                g = page.Graphics
                dy = 0
            End If
            For Each mode In modes
                blendMode = CType(mode, BlendMode)
                If Not g.IsBlendModeSupported(blendMode) Then
                    Continue For
                End If

                x = margin + w * col
                y = margin + h * row + dy
                r = New RectangleF(x, y, w, h)

                g.BlendMode = BlendMode.Normal
                g.DrawImage(iback, r, Nothing, ImageAlign.StretchImage)
                g.BlendMode = blendMode
                g.DrawImage(ifore, r, Nothing, ImageAlign.StretchImage)
                g.BlendMode = BlendMode.Normal

                ' Caption:
                tl.Clear()
                tl.Append(blendMode.ToString())
                tl.PerformLayout(True)
                rc = tl.ContentRectangle
                rc.Offset(x, y)
                rc.Inflate(4, 2)
                g.FillRectangle(rc, Color.White)
                g.DrawTextLayout(tl, New PointF(x, y))
                col += 1
                If col = NCOLS Then
                    col = 0
                    row += 1
                End If
            Next
        Next
        ' Text blends:
        page = doc.Pages(1)
        g = page.Graphics
        Dim trc = Util.AddNote(
            "Below are supported blend mode names rendered into rectangles using the corresponding blend mode. " &
            "Each rectangle is first filled by the spectrum image using BlendMode.Normal, " &
            "then black and white texts are drawn using the current blend mode, " &
            "finally the same spectrum image is drawn using BlendMode.Difference to black out the background. " &
            "Names prefixed with 'B:' are drawn in black, " &
            "while names prefixed with 'W:' are drawn in white. " &
            "Most combinations yield rather colorful results, but for some the results are invisible.",
            page,
            New RectangleF(margin, margin + h * row + 12, page.Bounds.Width - margin * 2, 0))

        Dim yoff = CInt(Fix(trc.Bottom)) + 12
        tl.DefaultFormat.FontBold = True
        tl.DefaultFormat.FontSize = 16
        h = CInt(Fix(g.MeasureString("QWERTY", tl.DefaultFormat).Height * 1.4F)) * 2
        tl.MaxWidth = w
        tl.MaxHeight = h
        tl.MarginTop = (h - h / 1.4F) / 2

        tl.DefaultFormat.ForeColor = Color.Black
        Dim tfWhite = New TextFormat(tl.DefaultFormat) With {.ForeColor = Color.White}

        row = 0
        col = 0
        For Each mode In modes
            blendMode = CType(mode, BlendMode)
            If Not g.IsBlendModeSupported(blendMode) Then
                Continue For
            End If

            x = margin + w * col
            y = yoff + h * row
            r = New RectangleF(x, y, w, h)

            ' Draw spectrum image normally:
            g.BlendMode = BlendMode.Normal
            g.DrawImage(ispectr, r, Nothing, ImageAlign.StretchImage)
            ' Draw blend mode name using the current blend mode:
            tl.Clear()
            tl.AppendLine($"B: {blendMode}")
            tl.Append($"W: {blendMode}", tfWhite)
            tl.PerformLayout(True)
            rc = tl.ContentRectangle
            rc.Offset(x, y)
            rc.Inflate(4, 2)
            ' Current blend mode:
            g.BlendMode = blendMode
            g.DrawTextLayout(tl, New PointF(x, y))
            ' Draw spectrum image again using BlendMode.Difference
            ' to produce (mostly) colorful text on black background:
            g.BlendMode = BlendMode.Difference
            g.DrawImage(ispectr, r, Nothing, ImageAlign.StretchImage)
            ' Draw a rectangle to mark the current area:
            g.BlendMode = BlendMode.Normal
            g.DrawRectangle(r, Color.Gray)
            col += 1
            If col = NCOLS Then
                col = 0
                row += 1
            End If
        Next
        ' Done:
        doc.Save(stream)
        Return doc.Pages.Count
    End Function
End Class