GcDocsDataSheet.vb
'' 完毕:
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

'' 该示例生成有关新产品的两页数据表
'' 文档解决方案产品线。
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)

    '' 该示例的主要入口点:
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        _fc.RegisterDirectory(Path.Combine("Resources", "Fonts"))
        '' 第一页:
        Page1(doc)
        '' 第二页:
        Page2(doc)
        '' 保存 PDF:
        doc.Save(stream)
        '' 保存文档后处理图像:
        _disposables.ForEach(Sub(d_) d_.Dispose())
        '' 完毕:
        Return doc.Pages.Count
    End Function

    Private Function GetImage(ByVal path As String) As IImage
        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("Document Solutions",
            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 IImage, 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 dspdf = 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,
            "Document Solutions 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 dspdf
            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,
            "Document Solutions 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 = "mescius.com"
        Dim ftr1 = "(c) MESCIUS 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