GcDocsDataSheet.vb
''
'' This code is part of GrapeCity Documents for PDF samples.
'' Copyright (c) GrapeCity, 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.Pdf.AcroForms
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Common
Imports GrapeCity.Documents.Drawing
Imports System.Numerics

'' This sample generates a two-page data sheet about the new
'' GrapeCity Documents product line.
Public Class GcDocsDataSheet
    Private _fc As New FontCollection()
    Private _darkGray As Color = Color.FromArgb(64, 64, 64)
    Private _lightGray As Color = Color.FromArgb(232, 232, 232)
    Private _blue As Color = Color.FromArgb(&H3B, &H5C, &HAA)
    Private _disposables As List(Of IDisposable) = New List(Of IDisposable)

    '' Main entry point of this sample
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        _fc.RegisterDirectory(Path.Combine("Resources", "Fonts"))
        '' First page:
        Page1(doc)
        '' Second page:
        Page2(doc)
        '' Save the PDF:
        doc.Save(stream)
        '' Dispose images after the document has been saved:
        _disposables.ForEach(Sub(d_) d_.Dispose())
        '' Done:
        Return doc.Pages.Count
    End Function

    Private Function GetImage(ByVal path As String) As Image
        Dim Image = ImageFromFile(path)
        _disposables.Add(Image)
        Return Image
    End Function

    Private Sub Page1(ByVal doc As GcPdfDocument)
        Dim page = doc.Pages.Add()
        Dim g = page.Graphics
        Dim tl = New TextLayout(g.Resolution) With {.FontCollection = _fc}

        Dim gclogo = GetImage(Path.Combine("Resources", "ImagesBis", "gc-logo-100px.png"))
        Dim gclogoRc = New RectangleF(36, 0, 72 * 1.8F, 72)
        Dim rcs As RectangleF() = Nothing
        g.DrawImage(gclogo, gclogoRc, Nothing,
            New ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Center, True, True, True, False, False), rcs)
        g.DrawLine(rcs(0).Right + 10, rcs(0).Top, rcs(0).Right + 10, rcs(0).Bottom, _darkGray, 1)

        tl.Clear()
        tl.ParagraphAlignment = ParagraphAlignment.Center
        tl.MaxHeight = gclogoRc.Height
        tl.Append("Developer Solutions",
            New TextFormat() With {.FontName = "open sans", .FontSize = 16, .ForeColor = _darkGray})
        tl.PerformLayout(True)
        g.DrawTextLayout(tl, New PointF(gclogoRc.Right + 20, gclogoRc.Y))

        Dim back = GetImage(Path.Combine("Resources", "ImagesBis", "GCDocs-datasheet-sm.png"))
        Dim backRcClip = New RectangleF(0, 72, page.Size.Width, page.Size.Width - 72 * 1.75F)
        Dim backRc = New RectangleF(-72, -72 * 4, page.Size.Width + 72 * 4, page.Size.Height + 72 * 4)
        g.DrawImage(back, backRc, backRcClip, ImageAlign.StretchImage)
        g.FillRectangle(New RectangleF(0, backRcClip.Bottom, page.Size.Width, page.Size.Height - backRcClip.Bottom), _lightGray)
        g.DrawLine(backRcClip.X, backRcClip.Bottom, backRcClip.Right, backRcClip.Bottom, Color.White, 1, DashStyle.Solid)
        g.DrawLine(backRcClip.X, backRcClip.Bottom + 1, backRcClip.Right, backRcClip.Bottom + 1, _darkGray, 1, DashStyle.Solid)

        Dim blueRc = New RectangleF(0, backRcClip.Y, page.Size.Width, 72 * 4)
        g.FillRectangle(blueRc, Color.FromArgb(220, _blue))

        blueRc.Inflate(0, -36)
        g.FillRectangle(New RectangleF(blueRc.Location, New SizeF(10, blueRc.Height)), Color.White)

        blueRc.Inflate(-36, 0)
        tl.Clear()
        tl.ParagraphAlignment = ParagraphAlignment.Near
        tl.MaxWidth = blueRc.Width
        tl.MaxHeight = blueRc.Height
        tl.Append("NEW PRODUCT LINE",
            New TextFormat() With {.FontName = "open sans semibold", .FontSize = 20, .ForeColor = Color.White})
        tl.PerformLayout(True)
        g.DrawTextLayout(tl, blueRc.Location)

        Dim midRc = New RectangleF(blueRc.X, blueRc.Y + tl.ContentHeight, blueRc.Width, blueRc.Height - tl.ContentHeight)

        tl.Clear()
        tl.ParagraphAlignment = ParagraphAlignment.Far
        tl.Append(
            "Take total control of your digital documents with this NEW collection of ultra-fast, low-footprint document APIs for .NET Standard 2.0. These intuitive, extensible APIs " +
            "allow you to create, load, modify, and save Excel spreadsheets and PDF files in any .NET Standard 2.0 application",
            New TextFormat() With {.FontName = "open sans light", .FontSize = 14, .ForeColor = Color.White})
        tl.PerformLayout(True)
        g.DrawTextLayout(tl, blueRc.Location)

        midRc.Height -= tl.ContentHeight
        midRc.Inflate(0, -20)

        Dim hex = GetImage(Path.Combine("Resources", "ImagesBis", "gcd-hex-logo-white.png"))
        Dim hexRc = New RectangleF(midRc.Location, New SizeF(midRc.Height, midRc.Height))
        g.DrawImage(hex, hexRc, Nothing, ImageAlign.StretchImage)

        tl.Clear()
        tl.ParagraphAlignment = ParagraphAlignment.Center
        tl.MaxHeight = midRc.Height
        tl.Append("GrapeCity Documents",
            New TextFormat() With {.FontName = "open sans semibold", .FontSize = 26, .ForeColor = Color.White})
        tl.PerformLayout(True)
        g.DrawTextLayout(tl, New PointF(midRc.X + midRc.Height + 10, midRc.Y))

        Dim pointRc = New RectangleF(0, backRcClip.Bottom, page.Size.Width / 2, (page.Size.Height - backRcClip.Bottom) / 2 - 12)
        tl.ParagraphAlignment = ParagraphAlignment.Near
        tl.MaxWidth = pointRc.Width
        tl.MaxHeight = pointRc.Height
        tl.MarginLeft = 80
        tl.MarginTop = 25
        tl.MarginBottom = 0

        Dim addPoint As Action(Of Image, String, String) =
            Sub(img, caption, text)
                Dim imgRect = New RectangleF(pointRc.X + 20, pointRc.Y + tl.MarginTop, 48, 48)
                g.DrawImage(img, imgRect, Nothing, New ImageAlign() With {.AlignHorz = ImageAlignHorz.Center, .AlignVert = ImageAlignVert.Center, .BestFit = True})
                tl.Clear()
                tl.AppendLine(caption, New TextFormat() With {.FontName = "open sans semibold", .FontSize = 11})
                tl.Append(text, New TextFormat() With {.FontName = "open sans light", .FontSize = 11})
                tl.PerformLayout(True)
                If Not tl.ContentHeightFitsInBounds Then
                    Throw New Exception("Unexpected: text overflow.")
                End If
                g.DrawTextLayout(tl, pointRc.Location)
            End Sub

        Dim drawCircle As Action(Of PointF) =
            Sub(p)
                Dim d = 128.0F
                Dim angle = (16 * Math.PI) / 180.0F
                g.Transform =
                    Matrix3x2.CreateTranslation(-d / 2, -d / 2) *
                    Matrix3x2.CreateRotation(angle) *
                    Matrix3x2.CreateTranslation(p.X + d / 2, p.Y + d / 2)

                Dim rr = New RectangleF(PointF.Empty, New SizeF(d, d))
                For i = 0 To 2
                    g.FillEllipse(rr, Color.FromArgb(30 + i * 10, _darkGray))
                    rr.Inflate(-1, -1)
                Next
                g.FillEllipse(rr, _darkGray)
                rr.Inflate(-1, -1)
                g.FillEllipse(rr, Color.White)
                rr.Inflate(-6, -6)
                g.FillEllipse(rr, _darkGray)

                tl.Clear()
                tl.MaxHeight = d
                tl.MaxWidth = d
                tl.MarginLeft = 0
                tl.MarginRight = 0
                tl.MarginTop = 0
                tl.MarginBottom = 0
                tl.TextAlignment = TextAlignment.Center
                tl.ParagraphAlignment = ParagraphAlignment.Center
                tl.ParagraphSpacing = -4
                Dim tf = New TextFormat() With {.FontName = "open sans light", .FontSize = 18, .ForeColor = Color.White}
                tl.Append("DEPLOY" + vbCrLf + "TO", tf)
                tl.Append(" AZURE" + vbCrLf, New TextFormat(tf) With {.FontName = "open sans semibold"})
                tl.Append(" ")
                tl.PerformLayout(True)
                g.DrawTextLayout(tl, PointF.Empty)
                g.Transform = Matrix3x2.Identity
            End Sub

        addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-.NET.png")),
            "Expand the reach of modern apps",
            "With full support for .NET Standard 2.0, you can target multiple platforms, devices, and cloud with one code base.")

        pointRc.Offset(0, pointRc.Height)
        addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-code.png")),
            "Comprehensive, highly programmable",
            "Do more with your Excel spreadsheets and PDFs: these APIs support Windows, Mac, Linux, and a wide variety of features for your documents.")

        pointRc.Offset(pointRc.Width, -pointRc.Height)
        tl.MarginRight = 30
        addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-speed.png")),
            "High-speed, small footprint",
            "The API architecture is designed to generate large, optimized documents, fast—while remaining lightweight and extensible.")

        pointRc.Offset(0, pointRc.Height)
        addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-nodependences.png")),
            "No dependencies",
            "Generate and edit digital documents with no Acrobat or Excel dependencies.")

        g.FillRectangle(New RectangleF(0, page.Size.Height - 16, page.Size.Width, 16), _darkGray)

        drawCircle(New PointF(page.Size.Width - 160, backRcClip.Bottom - 105))

    End Sub

    Private Class Bullet
        Public Property Caption As String
        Public Property Points As List(Of String)
    End Class

    Private Sub Page2(ByVal doc As GcPdfDocument)
        Dim page = doc.Pages.Add()
        Dim g = page.Graphics
        Dim tl = New TextLayout(g.Resolution) With {.FontCollection = _fc}
        Dim col0X = 36
        Dim colWidth = page.Size.Width / 3 - 40
        Dim colGap = 20
        Dim vgap = 10
        Dim ser1Y = 100
        Dim ser2Y = 72 * 6
        Dim h = 45

        Dim gcpdf = New List(Of Bullet) From
            {
                New Bullet() With {.Caption = "Advanced Text Handling", .Points = New List(Of String) From {
                    "Standard PDF Fonts, Truetype Fonts, Open type Fonts, WOFF Fonts, system font loading, font embedding, fallback and linked fonts, EUDC fonts",
                    "Advanced text rendering features",
                    "Special character support"
                }},
                New Bullet() With {.Caption = "Cross-Platform, Cross-Framework compatibility", .Points = New List(Of String) From {
                    ".NET Standard 2.0",
                    ".NET Core 2.0",
                    ".NET Framework",
                    "Mono",
                    "Xamarin iOS",
                    "VSTO-style API"
                }},
                New Bullet() With {.Caption = "Security", .Points = New List(Of String) From {
                    "Encryption and decrpyption",
                    "User and owner passwords",
                    "AllowCopyContent, AllowEditAnnotations, AllowEditContent, AllowPrint",
                    "Digital Signatures"
                }},
                New Bullet() With {.Caption = "Annotations", .Points = New List(Of String) From {
                    "Figures",
                    "Comments",
                    "Text",
                    "Signatures",
                    "Stamps",
                    "Modify, extract or delete annotations from existing PDFs"
                }},
                New Bullet() With {.Caption = "Fillable Form Fields", .Points = New List(Of String) From {
                    "Textbox",
                    "Checkbox",
                    "Combobox",
                    "Listbox",
                    "Radio button",
                    "Push button",
                    "Signature field",
                    "Modify, extract or delete form fields from existing PDFs"
                }},
                New Bullet() With {.Caption = "Navigation", .Points = New List(Of String) From {
                    "Outlines",
                    "Hyperlinks"
                }},
                New Bullet() With {.Caption = "Additional Features", .Points = New List(Of String) From {
                    "50 barcodes and properties",
                    "Create PDF/A files",
                    "Maintain document history with document properties",
                    "Generate linearized PDFs for fast web view",
                    "Full image and graphic support on all platforms",
                    "Add and delete pages",
                    "Chage page sizes",
                    "Page orientation"
                }}
            }

        Dim gcexcel = New List(Of Bullet) From
            {
                New Bullet() With {.Caption = "Fast and Efficient", .Points = New List(Of String) From {
                    "Lightweight",
                    "Optimized for processing large Excel documents quickly"
                }},
                New Bullet() With {.Caption = "Cross-Platform, Cross-Framework compatibility", .Points = New List(Of String) From {
                    ".NET Standard 2.0",
                    ".NET Core 2.0",
                    ".NET Framework",
                    "Mono",
                    "Xamarin.iOS",
                    "VSTO-style API"
                }},
                New Bullet() With {.Caption = "Data Visualization", .Points = New List(Of String) From {
                    "Shapes and pictures",
                    "Slicers",
                    "Sparklines",
                    "Charts"
                }},
                New Bullet() With {.Caption = "Powerful Calculation Engine", .Points = New List(Of String) From {
                    "450+ Excel functions",
                    "Calculate",
                    "Query",
                    "Generate",
                    "Sorting",
                    "Filtering",
                    "Grouping"
                }},
                New Bullet() With {.Caption = "Seamless Excel Compatibility", .Points = New List(Of String) From {
                    "Import and export Excel files",
                    "Export to PDF",
                    "Encrypt files",
                    "Workbooks and worksheets",
                    "Cell range operations",
                    "Pivot and Excel tables",
                    "Data validation",
                    "Annotations",
                    "Comments"
                }},
                New Bullet() With {.Caption = "Conditional Formatting Rules", .Points = New List(Of String) From {
                    "Cell value",
                    "Average",
                    "Color scale",
                    "Data bar",
                    "Icon sets",
                    "Top and Bottom",
                    "Unique",
                    "Expression"
                }},
                New Bullet() With {.Caption = "Flexible Themes And Components", .Points = New List(Of String) From {
                    "Customizable themes",
                    "Configurable components",
                    "Summary data",
                    "Custom styles",
                    "Embedded drawing objects",
                    "Integrated calculation engine"
                }}
            }

        Dim addHeader As Action(Of Single, String, String) =
            Sub(y, caption, text)
                Dim bluerc = New RectangleF(0, y, 28, h)
                g.FillRectangle(bluerc, _blue)
                Dim caprc = New RectangleF(bluerc.Right, y, 72 * 2.75F, h)
                g.FillRectangle(caprc, _lightGray)
                caprc.X = col0X
                caprc.Width -= col0X - bluerc.Width
                g.DrawString(caption, New TextFormat() With {.FontName = "open sans semibold", .FontSize = 12}, caprc, TextAlignment.Leading, ParagraphAlignment.Center, False)
                Dim textrc = New RectangleF(caprc.Right, caprc.Top, page.Size.Width - caprc.Right, caprc.Height)
                textrc.Inflate(-10, 0)
                g.DrawString(text, New TextFormat() With {.FontName = "open sans light", .FontSize = 9}, textrc, TextAlignment.Leading, ParagraphAlignment.Center, True)
            End Sub

        Dim addList As Func(Of PointF, String, List(Of String), RectangleF) =
            Function(ByVal pt, ByVal caption, ByVal items)
                Dim tf = New TextFormat() With {.FontName = "open sans light", .FontSize = 9}
                Dim ret = New RectangleF(pt, SizeF.Empty)
                tl.Clear()
                tl.MaxWidth = colWidth
                tl.AppendLine(caption, New TextFormat() With {.FontName = "open sans", .FontBold = True, .FontSize = 9})
                tl.PerformLayout(True)
                g.DrawTextLayout(tl, pt)
                ret.Width = tl.ContentWidth
                ret.Height = tl.ContentHeight
                pt.Y += ret.Height
                tl.Clear()
                Dim itemPrefix = $"{ChrW(&H2022)}  "
                tl.FirstLineIndent = -g.MeasureStringWithTrailingWhitespace(itemPrefix, tf).Width
                For Each item In items
                    tl.AppendLine(itemPrefix + item, tf)
                Next
                tl.PerformLayout(True)
                g.DrawTextLayout(tl, pt)
                ret.Width = Math.Max(ret.Width, tl.ContentWidth)
                ret.Height += tl.ContentHeight
                Return ret
            End Function

        addHeader(45,
            "GrapeCity Documents for PDF",
            "This high-speed, feature-rich PDF document API for .NET Standard 2.0 gives you total " +
            "control of your PDF documents, with no dependencies on Adobe Acrobat.Generate, " +
            "edit, and store feature - rich PDF documents without compromising design or features.")

        Dim ipt = New PointF(col0X, ser1Y)
        For Each bullet In gcpdf
            Dim rc = addList(ipt, bullet.Caption, bullet.Points)
            If (rc.Bottom < ser2Y - 120) Then
                ipt = New PointF(rc.X, rc.Bottom + vgap)
            Else
                ipt = New PointF(rc.X + colWidth + colGap, ser1Y)
            End If
        Next

        addHeader(ser2Y,
            "GrapeCity Documents for Excel",
            "Generate high-performance Excel spreadsheets with no dependencies on Excel! " +
            "Generate, convert, calculate, format, and parse spreadsheets in any app.")

        Dim topY = ser2Y + h + 10
        ipt = New PointF(col0X, topY)
        For Each bullet In gcexcel
            Dim rc = addList(ipt, bullet.Caption, bullet.Points)
            If (rc.Bottom < page.Size.Height - 100) Then
                ipt = New PointF(rc.X, rc.Bottom + vgap)
            Else
                ipt = New PointF(rc.X + colWidth + colGap, topY)
            End If
        Next

        Dim hdrRc = New RectangleF(28, 0, page.Size.Width - 28 * 2, 36)
        g.FillRectangle(hdrRc, _darkGray)
        Dim w = hdrRc.Width / 7
        Dim hdrs = New String() {"Create", "Load", "Edit", "Save", "Analyze"}

        Dim hdrTf = New TextFormat() With {.FontName = "open sans", .FontSize = 12, .ForeColor = Color.White}
        Dim trc = New RectangleF(hdrRc.X + w, hdrRc.Y, w, hdrRc.Height)
        For i = 0 To hdrs.Length - 1
            g.DrawString(hdrs(i), hdrTf, trc, TextAlignment.Center, ParagraphAlignment.Center, False)
            If (i < hdrs.Length - 1) Then
                g.DrawLine(trc.Right, trc.Top + 12, trc.Right, trc.Bottom - 12, Color.White, 1)
            End If
            trc.Offset(w, 0)
        Next

        Dim ftrRc = New RectangleF(0, page.Size.Height - 36, page.Size.Width, 36)
        g.FillRectangle(ftrRc, _darkGray)
        Dim ftr0 = "GrapeCity.com"
        Dim ftr1 = "© 2018 GrapeCity, Inc.All rights reserved.All other product and brand names are trademarks and/or registered trademarks of their respective holders."
        ftrRc.Inflate(-col0X, -5)
        hdrTf.FontSize = 12
        g.DrawString(ftr0, hdrTf, ftrRc, TextAlignment.Leading, ParagraphAlignment.Near, False)
        hdrTf.FontSize = 6
        g.DrawString(ftr1, hdrTf, ftrRc, TextAlignment.Leading, ParagraphAlignment.Far, False)
        ftrRc.Inflate(0, -5)
        g.DrawImage(GetImage(Path.Combine("Resources", "ImagesBis", "logo-GC-white.png")), ftrRc, Nothing,
            New ImageAlign() With {.AlignHorz = ImageAlignHorz.Right, .AlignVert = ImageAlignVert.Center, .BestFit = True})
    End Sub
End Class