VisualSignature.vb
'' 
'' このコードは、DioDocs for PDF のサンプルの一部として提供されています。
'' Copyright (c) GrapeCity inc. All rights reserved.
'' 
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.AcroForms
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing
Imports System.Security.Cryptography.X509Certificates
Imports GrapeCity.Documents.Pdf.Annotations
Imports GcPdfWeb

'' このサンプルは、SignatureField と署名画像を使用して、PDF を作成し 
'' .pfx ファイルで署名する方法を示します。
'' また、サンプルは署名されたファイルを別の GcPdfDocument インスタンスに読み込み、
'' 署名を検証します。
'' このサンプルは SignDoc サンプルと同じですが、署名を表す画像を追加します。
Public Class VisualSignature
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim page = doc.NewPage()
        Dim tf = New TextFormat() With {.Font = StandardFonts.Times, .FontSize = 14}
        page.Graphics.DrawString(
            $"電子署名のサンプルです{vbCrLf}このPDFは表示している印影画像に署名されています。",
            tf, New PointF(72, 72))

        page.Graphics.DrawString(
            $"注意:署名に使用している証明書、印影はテスト用です。{vbCrLf}ブラウザのビルトインビューアによっては署名が表示されない場合があります。",
            tf, New PointF(72, 72 * 2))

        '' テスト証明書を初期化します。
        Dim pfxPath = Path.Combine("Resources", "Misc", "GcPdfTest.pfx")
        Dim cert = New X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
                X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable)
        Dim sp = New SignatureProperties() With
        {
            .Certificate = cert,
            .Location = "DioDocs Sample Browser",
            .SignerName = "株式会社ディオドック"
        }

        '' 署名を表す画像を追加します。
        sp.SignatureAppearance.Image = Image.FromFile(Path.Combine("Resources", "ImagesBis", "kaku_in.png"))
        sp.SignatureAppearance.CaptionImageRelation = GrapeCity.Documents.Pdf.Annotations.CaptionImageRelation.ImageOnly

        '' 署名を保持する署名フィールドを初期化します。
        Dim sf = New SignatureField()
        sf.Widget.Rect = New RectangleF(72 * 2, 72 * 2.5F, 72 * 2, 72 * 2)
        sf.Widget.Page = page
        sf.Widget.BackColor = Color.LightSeaGreen
        sf.Widget.TextFormat.Font = StandardFonts.Helvetica
        sf.Widget.ButtonAppearance.Caption = $"署名者: {sp.SignerName}{vbCrLf}場所: {sp.Location}"
        '' 文書に署名フィールドを追加します。
        doc.AcroForm.Fields.Add(sf)
        '' 署名フィールドと署名プロパティを結びつけます。
        sp.SignatureField = sf

        '' 署名して文書を保存します。
        '' 注意:
        '' - 署名と保存は一連の操作であり、2つは分離できません。
        '' - Sign() メソッドに渡されたストリームは読み込み可能でなければなりません。
        doc.Sign(sp, stream)

        '' ストリームを巻き戻して、作成した文書を別の GcPdfDocument 
        '' オブジェクトに読み込み、署名を確認します。
        stream.Seek(0, SeekOrigin.Begin)
        Dim doc2 = New GcPdfDocument()
        doc2.Load(stream)
        Dim sf2 = CType(doc2.AcroForm.Fields(0), SignatureField)
        If Not sf2.Value.VerifySignature() Then
            Throw New Exception("Failed to verify the signature")
        End If

        '' 終了(生成および署名された文書はすでに 'stream' に保存されています)。
        Return doc.Pages.Count
    End Function
End Class